[{"id":3684854,"web_url":"http://patchwork.ozlabs.org/comment/3684854/","msgid":"<CALvbMcCYamEkZ+2P5T12A2j0XQFZ4T4xpKC0fiNkDhXL_sHoKw@mail.gmail.com>","list_archive_url":null,"date":"2026-04-30T16:58:13","subject":"Re: [PATCH] backprop: Add demand-bit handling. [PR113487]","submitter":{"id":91428,"url":"http://patchwork.ozlabs.org/api/people/91428/","name":"Andrew Pinski","email":"andrew.pinski@oss.qualcomm.com"},"content":"On Thu, Apr 30, 2026 at 7:44 AM Robin Dapp <rdapp.gcc@gmail.com> wrote:\n>\n> Hi,\n>\n> This patch adds backpropagation of demand-bit information to the\n> backprop pass.  It is intended to catch cases like this\n>\n>   int\n>   foo (int in)\n>     {\n>       int a = in & 0xff;\n>       int b = a << 1;\n>       int c = b & 0xf;\n>       return c;\n>     }\n>\n> where we can propagate B's demand of 0xf back to IN and elide the\n> & 0xff masking.  This works in situations where forward-looking\n> optimizations like in match.pd fail, for example due to non-single\n> use.\n>\n> I tried to keep the implementation simple at first, but it grew\n> over time and now handles BIT_AND_EXPR, BIT_IOR_EXPR, BIT_XOR_EXPR,\n> MULT_EXPR, LSHIFT_EXPR, RSHIFT_EXPR, and PLUS_EXPR, MINUS_EXPR.\n>\n> The most important case is surely eliding masks: Once the demand has reached\n> a BIT_AND_EXPR and we see that it does not exceed what we mask off anyway, we\n> elide it.  In SPECint 2017 this hits a couple hundred times, predominantly gcc\n> and perlbench, albeit not in very hot code paths.\n>\n> Bootstrapped and regtested on x86, power10, and aarch64.\n> Regtested on riscv64.\n\nI was just looking into a related case yesterday:\n```\nunsigned f1(unsigned a, unsigned b)\n{\n  return ((a & ~1) ^ b ) ^ 1;\n}\nunsigned f2(unsigned a, unsigned b)\n{\n  return ((a & ~1) | b ) | 1;\n}\n```\nI have not check but does this patch handle these cases?\nThe first one is derived from\nhttps://github.com/llvm/llvm-project/issues/195019 (which comes\noriginally from cpython sha1 code it seems).\nHaving a generic method of removing the BIT_AND_EXPR here rather than\njust match/reassociation is definitely a good thing.\nNote I have not reviewed this patch otherwise.\n\nThanks,\nAndrea Pinski\n\n\n>\n> Regards\n>  Robin\n>\n>         PR tree-optimization/113487\n>         PR tree-optimization/122209\n>\n> gcc/ChangeLog:\n>\n>         * gimple-ssa-backprop.cc (usage_info::intersection_identity):\n>         Add demand-bit handling.\n>         (usage_info::is_useful): Ditto.\n>         (dump_usage_info): Log demand bits.\n>         (backprop::process_assign_use): Handle demand bits.\n>         (backprop::process_phi_use): Ditto.\n>         (backprop::intersect_uses): Ditto.\n>         (backprop::process_var): Ditto.\n>         (backprop::optimize_assign): Elide mask if possible.\n>\n> gcc/testsuite/ChangeLog:\n>\n>         * gcc.dg/tree-ssa/backprop-bits-1.c: New test.\n>         * gcc.dg/tree-ssa/backprop-bits-2.c: New test.\n>         * gcc.dg/tree-ssa/backprop-bits-3.c: New test.\n>         * gcc.dg/tree-ssa/backprop-bits-4.c: New test.\n>         * gcc.dg/tree-ssa/backprop-bits-5.c: New test.\n>         * gcc.dg/tree-ssa/backprop-bits-6.c: New test.\n>         * gcc.dg/tree-ssa/backprop-bits-7.c: New test.\n>         * gcc.dg/tree-ssa/backprop-bits-8.c: New test.\n> ---\n>  gcc/gimple-ssa-backprop.cc                    | 435 ++++++++++++++++--\n>  .../gcc.dg/tree-ssa/backprop-bits-1.c         |  16 +\n>  .../gcc.dg/tree-ssa/backprop-bits-2.c         |  29 ++\n>  .../gcc.dg/tree-ssa/backprop-bits-3.c         |  29 ++\n>  .../gcc.dg/tree-ssa/backprop-bits-4.c         |  34 ++\n>  .../gcc.dg/tree-ssa/backprop-bits-5.c         |  39 ++\n>  .../gcc.dg/tree-ssa/backprop-bits-6.c         |  18 +\n>  .../gcc.dg/tree-ssa/backprop-bits-7.c         |  41 ++\n>  .../gcc.dg/tree-ssa/backprop-bits-8.c         |  31 ++\n>  9 files changed, 643 insertions(+), 29 deletions(-)\n>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-1.c\n>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-2.c\n>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-3.c\n>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-4.c\n>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-5.c\n>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-6.c\n>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-7.c\n>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-8.c\n>\n> diff --git a/gcc/gimple-ssa-backprop.cc b/gcc/gimple-ssa-backprop.cc\n> index 3ac44116d27..0e36489691b 100644\n> --- a/gcc/gimple-ssa-backprop.cc\n> +++ b/gcc/gimple-ssa-backprop.cc\n> @@ -23,12 +23,13 @@ along with GCC; see the file COPYING3.  If not see\n>     fully or partially dead code, but the main focus is simplifying\n>     computations.\n>\n> -   At the moment the pass only handles one piece of information: whether the\n> -   sign of a value matters, and therefore whether sign-changing operations\n> -   can be skipped.  The pass could be extended to more interesting\n> -   information in future, such as which bits of an integer are significant.\n> +   The pass only handles two distinct properties:\n> +      (a) Whether the sign of a value matters, and therefore whether\n> +         sign-changing operations can be skipped.\n> +      (b) The bits a variable demands.  This opens up possibilities to\n> +         elide redundant bit masking.\n>\n> -   For example, take the function:\n> +   For an example of (a), take the function:\n>\n>       double\n>       f (double *a, int n, double start)\n> @@ -48,6 +49,28 @@ along with GCC; see the file COPYING3.  If not see\n>     with start.  Since there are no other uses of the fabs result,\n>     the call would get deleted as dead.\n>\n> +   A typical case for (b) is:\n> +\n> +     void use (unsigned);\n> +\n> +     void\n> +     foo (unsigned x)\n> +     {\n> +       unsigned a = x & 0xff;\n> +       unsigned b = a * 4;\n> +       use (b & 0x10);\n> +       use (b & 0xe0);\n> +     }\n> +\n> +   Both use sites of B mask it and we cannot look through the multiplication to\n> +   elide the masking directly (via e.g. match.pd or ccp).  Seeing the demand\n> +   on B (= 0xf0), we can back-propagate it to B's definition and deduce which\n> +   bits A demands (= 0xf0 >> 2 = 0x3c).\n> +   Then, continuing at A's definition we see that there is no bit demand\n> +   outside of 0xff, so no necessary bit the mask would clear.  As a\n> +   consequence, the masking can be elided.\n> +\n> +\n>     The algorithm is:\n>\n>     (1) Do a post-order traversal of the blocks in the function, walking\n> @@ -110,9 +133,9 @@ namespace {\n>  class usage_info\n>  {\n>  public:\n> -  usage_info () : flag_word (0) {}\n> +  usage_info () : flag_word (0), needed_bits (-1) {}\n> +\n>    usage_info &operator &= (const usage_info &);\n> -  usage_info operator & (const usage_info &) const;\n>    bool operator == (const usage_info &) const;\n>    bool operator != (const usage_info &) const;\n>    bool is_useful () const;\n> @@ -129,6 +152,9 @@ public:\n>      /* All the flag bits as a single int.  */\n>      unsigned int flag_word;\n>    };\n> +\n> +  /* The live bits.  */\n> +  widest_int needed_bits;\n>  };\n>\n>  /* Return an X such that X & Y == Y for all Y.  This is the most\n> @@ -139,6 +165,7 @@ usage_info::intersection_identity ()\n>  {\n>    usage_info ret;\n>    ret.flag_word = -1;\n> +  ret.needed_bits = 0;\n>    return ret;\n>  }\n>\n> @@ -149,24 +176,15 @@ usage_info &\n>  usage_info::operator &= (const usage_info &other)\n>  {\n>    flag_word &= other.flag_word;\n> +  needed_bits = needed_bits | other.needed_bits;\n>    return *this;\n>  }\n>\n> -/* Return the intersection of *THIS and OTHER, i.e. a structure that\n> -   describes all uses covered by *THIS and OTHER.  */\n> -\n> -usage_info\n> -usage_info::operator & (const usage_info &other) const\n> -{\n> -  usage_info info (*this);\n> -  info &= other;\n> -  return info;\n> -}\n> -\n>  bool\n>  usage_info::operator == (const usage_info &other) const\n>  {\n> -  return flag_word == other.flag_word;\n> +  return flag_word == other.flag_word\n> +    && needed_bits == other.needed_bits;\n>  }\n>\n>  bool\n> @@ -180,7 +198,7 @@ usage_info::operator != (const usage_info &other) const\n>  bool\n>  usage_info::is_useful () const\n>  {\n> -  return flag_word != 0;\n> +  return flag_word != 0 || needed_bits != -1;\n>  }\n>\n>  /* Start a dump line about SSA name VAR.  */\n> @@ -203,6 +221,18 @@ dump_usage_info (FILE *file, tree var, usage_info *info)\n>        dump_usage_prefix (file, var);\n>        fprintf (file, \"sign bit not important\\n\");\n>      }\n> +  if (info->needed_bits != -1)\n> +    {\n> +      tree type = TREE_TYPE (var);\n> +      if (VECTOR_TYPE_P (type))\n> +       type = TREE_TYPE (type);\n> +      unsigned prec = TYPE_PRECISION (type);\n> +      wide_int mask = wide_int::from (info->needed_bits, prec, UNSIGNED);\n> +      dump_usage_prefix (file, var);\n> +      fprintf (file, \"demand bit mask: \");\n> +      print_hex (mask, file);\n> +      fprintf (file, \"\\n\");\n> +    }\n>  }\n>\n>  /* Represents one execution of the pass.  */\n> @@ -233,6 +263,7 @@ private:\n>    void complete_change (gimple *);\n>    void optimize_builtin_call (gcall *, tree, const usage_info *);\n>    void replace_assign_rhs (gassign *, tree, tree, tree, tree);\n> +  void build_nop_rhs (gassign *, tree);\n>    void optimize_assign (gassign *, tree, const usage_info *);\n>    void optimize_phi (gphi *, tree, const usage_info *);\n>\n> @@ -417,7 +448,12 @@ void\n>  backprop::process_assign_use (gassign *assign, tree rhs, usage_info *info)\n>  {\n>    tree lhs = gimple_assign_lhs (assign);\n> -  switch (gimple_assign_rhs_code (assign))\n> +  const usage_info *lhs_info = lookup_operand (lhs);\n> +  info->needed_bits = -1;\n> +\n> +  tree_code code = gimple_assign_rhs_code (assign);\n> +\n> +  switch (code)\n>      {\n>      case ABS_EXPR:\n>      case ABSU_EXPR:\n> @@ -430,17 +466,56 @@ backprop::process_assign_use (gassign *assign, tree rhs, usage_info *info)\n>          to C and D.  */\n>        if (rhs != gimple_assign_rhs1 (assign))\n>         {\n> -         const usage_info *lhs_info = lookup_operand (lhs);\n>           if (lhs_info)\n>             *info = *lhs_info;\n>         }\n>        break;\n>\n>      case MULT_EXPR:\n> -      /* In X * X, the sign of X doesn't matter.  */\n> -      if (gimple_assign_rhs1 (assign) == rhs\n> -         && gimple_assign_rhs2 (assign) == rhs)\n> -       info->flags.ignore_sign = true;\n> +       {\n> +         /* In X * X, the sign of X doesn't matter.  */\n> +         if (gimple_assign_rhs1 (assign) == rhs\n> +             && gimple_assign_rhs2 (assign) == rhs)\n> +           info->flags.ignore_sign = true;\n> +\n> +         tree type = TREE_TYPE (lhs);\n> +         if (VECTOR_TYPE_P (type))\n> +           type = TREE_TYPE (type);\n> +\n> +         tree other = (rhs == gimple_assign_rhs1 (assign))\n> +                      ? gimple_assign_rhs2 (assign)\n> +                      : gimple_assign_rhs1 (assign);\n> +         wide_int nz;\n> +\n> +         /* Given the output demand, we assume that all input bits not\n> +            higher than the output's highest set bit can contribute to the\n> +            output.  If we know that a number of low bits are zero, we\n> +            have a lower bound on the bits.\n> +            For a multiplication by a power of two there is no carry and\n> +            we can simply shift the output.\n> +            */\n> +         if (INTEGRAL_TYPE_P (type) && lhs_info\n> +             && lhs_info->needed_bits != -1\n> +             && (nz = get_nonzero_bits (other)).get_precision () != 0)\n> +           {\n> +             widest_int wnz = widest_int::from (nz, UNSIGNED);\n> +             HOST_WIDE_INT lo = wi::ctz (wnz);\n> +             HOST_WIDE_INT hi = wi::floor_log2 (lhs_info->needed_bits);\n> +\n> +             if (wnz == 0)\n> +               info->needed_bits = 0;\n> +             else if (wi::popcount (wnz) == 1)\n> +               info->needed_bits = lo > 0\n> +                 ? wi::lrshift (lhs_info->needed_bits, lo)\n> +                 : lhs_info->needed_bits;\n> +             else if (hi < lo)\n> +               info->needed_bits = 0;\n> +             else\n> +               info->needed_bits\n> +                 = wi::mask<widest_int> (hi - lo + 1, false);\n> +           }\n> +       }\n> +\n>        /* Fall through.  */\n>\n>      case NEGATE_EXPR:\n> @@ -449,12 +524,203 @@ backprop::process_assign_use (gassign *assign, tree rhs, usage_info *info)\n>          doesn't matter either.  */\n>        if (FLOAT_TYPE_P (TREE_TYPE (rhs)))\n>         {\n> -         const usage_info *lhs_info = lookup_operand (lhs);\n>           if (lhs_info)\n>             info->flags.ignore_sign = lhs_info->flags.ignore_sign;\n>         }\n>        break;\n>\n> +    case TRUNC_DIV_EXPR:\n> +       {\n> +         tree type = TREE_TYPE (rhs);\n> +         if (VECTOR_TYPE_P (type))\n> +           type = TREE_TYPE (type);\n> +         if (!INTEGRAL_TYPE_P (type) || !TYPE_UNSIGNED (type))\n> +           break;\n> +\n> +         tree rhs1 = gimple_assign_rhs1 (assign);\n> +         tree rhs2 = gimple_assign_rhs2 (assign);\n> +         if (rhs != rhs1 || TREE_CODE (rhs2) != INTEGER_CST)\n> +           break;\n> +\n> +         if (!lhs_info || lhs_info->needed_bits == -1)\n> +           break;\n> +\n> +         widest_int div = widest_int::from (wi::to_wide (rhs2), UNSIGNED);\n> +         if (div == 0)\n> +           break;\n> +\n> +         /* Opposite to multiplication, with division at least all LHS bits\n> +            contribute.  As the input is not smaller than the output, the\n> +            RHS determines the number of bits that contribute on top,\n> +            with the highest bit marking the upper bound.\n> +\n> +            An example is that we're looking for IN's bits that could\n> +            contribute to the known bits of A:\n> +\n> +              char a    =  in / 3;\n> +                   |\n> +              0b00001101 = ? /  3\n> +\n> +              =>\n> +\n> +              0b00001101 = 0b00??1101 / 3\n> +\n> +            So the lower bits come from the output (A), while the next higher\n> +            ones come from the division by 3.  */\n> +\n> +         HOST_WIDE_INT log_k = wi::exact_log2 (div);\n> +         if (log_k >= 0)\n> +           info->needed_bits = wi::lshift (lhs_info->needed_bits, log_k);\n> +         else\n> +           {\n> +             HOST_WIDE_INT needed_out\n> +               = wi::floor_log2 (lhs_info->needed_bits);\n> +             HOST_WIDE_INT needed_cst = wi::floor_log2 (div - 1) + 1;\n> +             HOST_WIDE_INT width = needed_out + needed_cst + 1;\n> +             unsigned prec = TYPE_PRECISION (type);\n> +             if (width >= (HOST_WIDE_INT) prec)\n> +               info->needed_bits = -1;\n> +             else\n> +               info->needed_bits = wi::mask<widest_int> (width, false);\n> +           }\n> +       }\n> +      break;\n> +\n> +    case BIT_AND_EXPR:\n> +       {\n> +         if (lhs_info)\n> +           info->needed_bits = lhs_info->needed_bits;\n> +\n> +         tree other;\n> +         if (rhs == gimple_assign_rhs1 (assign))\n> +           other = gimple_assign_rhs2 (assign);\n> +         else\n> +           other = gimple_assign_rhs1 (assign);\n> +\n> +         wide_int nz = get_nonzero_bits (other);\n> +         widest_int wnz (-1);\n> +         if (nz.get_precision () != 0)\n> +           wnz = widest_int::from (nz, UNSIGNED);\n> +         info->needed_bits &= wnz;\n> +       }\n> +      break;\n> +\n> +    case LSHIFT_EXPR:\n> +    case RSHIFT_EXPR:\n> +      if (rhs == gimple_assign_rhs1 (assign))\n> +       {\n> +         tree rhs2 = gimple_assign_rhs2 (assign);\n> +         if (TREE_CODE (rhs2) == INTEGER_CST\n> +             && lhs_info)\n> +           {\n> +             info->needed_bits = lhs_info->needed_bits;\n> +             widest_int shift_count\n> +               = widest_int::from (wi::to_wide (rhs2), UNSIGNED);\n> +\n> +             if (code == LSHIFT_EXPR)\n> +               info->needed_bits = wi::lrshift (info->needed_bits,\n> +                                                shift_count);\n> +             else\n> +               {\n> +                 if (TYPE_UNSIGNED (TREE_TYPE (rhs)))\n> +                   info->needed_bits = wi::lshift (info->needed_bits,\n> +                                                   shift_count);\n> +                 /* ??? Treat sign extension conservatively for now.  */\n> +                 else\n> +                   info->needed_bits = -1;\n> +               }\n> +           }\n> +       }\n> +      break;\n> +\n> +    case PLUS_EXPR:\n> +    case MINUS_EXPR:\n> +      if (rhs == gimple_assign_rhs1 (assign)\n> +         || rhs == gimple_assign_rhs2 (assign))\n> +       {\n> +         if (lhs_info)\n> +           info->needed_bits = lhs_info->needed_bits;\n> +\n> +         tree type = TREE_TYPE (rhs);\n> +         if (VECTOR_TYPE_P (type))\n> +           type = TREE_TYPE (type);\n> +\n> +         if (info->needed_bits != -1)\n> +           {\n> +             int hi = wi::floor_log2 (info->needed_bits);\n> +             info->needed_bits = wi::mask<widest_int> (hi + 1, false);\n> +           }\n> +       }\n> +      break;\n> +\n> +    case LROTATE_EXPR:\n> +    case RROTATE_EXPR:\n> +      if (rhs == gimple_assign_rhs1 (assign))\n> +       {\n> +         tree rhs2 = gimple_assign_rhs2 (assign);\n> +         tree type = TREE_TYPE (rhs);\n> +         if (VECTOR_TYPE_P (type))\n> +           type = TREE_TYPE (type);\n> +         HOST_WIDE_INT prec = TYPE_PRECISION (type);\n> +\n> +         if (TREE_CODE (rhs2) == INTEGER_CST)\n> +           {\n> +             widest_int count\n> +               = widest_int::from (wi::to_wide (rhs2), UNSIGNED);\n> +\n> +             if (lhs_info)\n> +               info->needed_bits = lhs_info->needed_bits;\n> +\n> +             if (code == LROTATE_EXPR)\n> +               info->needed_bits = wi::rrotate (info->needed_bits, count,\n> +                                                prec);\n> +             else\n> +               info->needed_bits = wi::lrotate (info->needed_bits, count,\n> +                                                prec);\n> +           }\n> +       }\n> +      break;\n> +\n> +    case NOP_EXPR:\n> +    case CONVERT_EXPR:\n> +       {\n> +         tree rhs1 = gimple_assign_rhs1 (assign);\n> +         tree rhs_type = TREE_TYPE (rhs1);\n> +         tree lhs_type = TREE_TYPE (lhs);\n> +         if (VECTOR_TYPE_P (lhs_type))\n> +           {\n> +             lhs_type = TREE_TYPE (lhs_type);\n> +             rhs_type = TREE_TYPE (rhs_type);\n> +           }\n> +\n> +         if (!INTEGRAL_TYPE_P (lhs_type) || !INTEGRAL_TYPE_P (rhs_type)\n> +             || !lhs_info)\n> +           break;\n> +\n> +         HOST_WIDE_INT rhs_prec = TYPE_PRECISION (rhs_type);\n> +         HOST_WIDE_INT lhs_prec = TYPE_PRECISION (lhs_type);\n> +\n> +         if (lhs_prec <= rhs_prec)\n> +           info->needed_bits = lhs_info->needed_bits;\n> +         else if (TYPE_UNSIGNED (rhs_type))\n> +           info->needed_bits\n> +             = lhs_info->needed_bits & wi::mask<widest_int> (rhs_prec, false);\n> +         else\n> +           /* As in the RSHIFT case above, treat sign extension\n> +              conservatively for now.  */\n> +           info->needed_bits = -1;\n> +       }\n> +      break;\n> +\n> +      /* The following expressions don't affect the needed bits so we can just\n> +        pass through the output.  */\n> +    case BIT_IOR_EXPR:\n> +    case BIT_XOR_EXPR:\n> +    case BIT_NOT_EXPR:\n> +      if (lhs_info)\n> +       info->needed_bits = lhs_info->needed_bits;\n> +      break;\n> +\n>      default:\n>        break;\n>      }\n> @@ -468,6 +734,8 @@ backprop::process_phi_use (gphi *phi, usage_info *info)\n>    tree result = gimple_phi_result (phi);\n>    if (const usage_info *result_info = lookup_operand (result))\n>      *info = *result_info;\n> +  else\n> +    info->needed_bits = -1;\n>  }\n>\n>  /* Make INFO describe all uses of RHS in STMT.  */\n> @@ -601,7 +869,10 @@ backprop::process_var (tree var)\n>        else if (info != *map_info)\n>         {\n>           /* Recording information that is less optimistic than before.  */\n> -         gcc_checking_assert ((info & *map_info) == info);\n> +         gcc_checking_assert ((info.flag_word & map_info->flag_word)\n> +                              == info.flag_word\n> +                              && (map_info->needed_bits\n> +                                  | info.needed_bits) == info.needed_bits);\n>           *map_info = info;\n>           if (dump_file && (dump_flags & TDF_DETAILS))\n>             dump_var_info (var, map_info, \"Updating information\");\n> @@ -813,13 +1084,24 @@ backprop::replace_assign_rhs (gassign *assign, tree lhs, tree rhs1,\n>    complete_change (assign);\n>  }\n>\n> +void\n> +backprop::build_nop_rhs (gassign *assign, tree lhs)\n> +{\n> +  prepare_change (lhs);\n> +  gimple_stmt_iterator gsi = gsi_for_stmt (assign);\n> +  gimple_assign_set_rhs_from_tree (&gsi, gimple_assign_rhs1\n> +                                  (assign));\n> +  complete_change (assign);\n> +}\n> +\n>  /* Optimize ASSIGN, an assignment to LHS, on the basis that INFO\n>     describes all uses of LHS.  */\n>\n>  void\n>  backprop::optimize_assign (gassign *assign, tree lhs, const usage_info *info)\n>  {\n> -  switch (gimple_assign_rhs_code (assign))\n> +  tree_code code = gimple_assign_rhs_code (assign);\n> +  switch (code)\n>      {\n>      case MULT_EXPR:\n>      case RDIV_EXPR:\n> @@ -842,6 +1124,101 @@ backprop::optimize_assign (gassign *assign, tree lhs, const usage_info *info)\n>                             strip_sign_op (gimple_assign_rhs3 (assign)));\n>        break;\n>\n> +    case BIT_AND_EXPR:\n> +    case BIT_IOR_EXPR:\n> +    case BIT_XOR_EXPR:\n> +      if (info->needed_bits != -1)\n> +       {\n> +         tree rhs2 = gimple_assign_rhs2 (assign);\n> +         if (TREE_CODE (rhs2) == INTEGER_CST)\n> +           {\n> +             bool elide_p = false;\n> +             widest_int mask\n> +               = widest_int::from (wi::to_wide (rhs2), UNSIGNED);\n> +\n> +             /* If we mask off bits that are being discarded later on anyway,\n> +                we can elide the mask.  */\n> +             if (code == BIT_AND_EXPR\n> +                 && (info->needed_bits & ~mask) == 0)\n> +               elide_p = true;\n> +\n> +             /* For IOR and XOR it's the other way around.  If all we modify\n> +                is a range outside of the needed bits, elide.  */\n> +             if ((code == BIT_IOR_EXPR || code == BIT_XOR_EXPR)\n> +                 && (info->needed_bits & mask) == 0)\n> +               elide_p = true;\n> +\n> +             if (elide_p)\n> +               {\n> +                 /* Just make the assignment a nop here.  */\n> +                 if (dump_file && (dump_flags & TDF_DETAILS))\n> +                   {\n> +                     fprintf (dump_file, \"Eliding redundant mask in \");\n> +                     print_gimple_stmt (dump_file, assign, 0, TDF_SLIM);\n> +                   }\n> +\n> +                 build_nop_rhs (assign, lhs);\n> +               }\n> +           }\n> +       }\n> +      break;\n> +\n> +    case PLUS_EXPR:\n> +    case MINUS_EXPR:\n> +      if (info->needed_bits != -1)\n> +       {\n> +         tree rhs2 = gimple_assign_rhs2 (assign);\n> +         wide_int nz = get_nonzero_bits (rhs2);\n> +         widest_int wnz (-1);\n> +         if (nz.get_precision ())\n> +           wnz = widest_int::from (nz, UNSIGNED);\n> +\n> +         widest_int shared_bits = info->needed_bits & wnz;\n> +         if (shared_bits == 0\n> +             && wi::ctz (wnz) > wi::floor_log2 (info->needed_bits))\n> +           {\n> +             if (dump_file && (dump_flags & TDF_DETAILS))\n> +               {\n> +                 fprintf (dump_file, \"Eliding redundant\"\n> +                                     \" addition/subtraction in \");\n> +                 print_gimple_stmt (dump_file, assign, 0, TDF_SLIM);\n> +               }\n> +\n> +             build_nop_rhs (assign, lhs);\n> +           }\n> +       }\n> +      break;\n> +\n> +    case LSHIFT_EXPR:\n> +      if (info->needed_bits != -1)\n> +       {\n> +         tree rhs2 = gimple_assign_rhs2 (assign);\n> +         if (TREE_CODE (rhs2) == INTEGER_CST)\n> +           {\n> +             widest_int shift_count\n> +               = widest_int::from (wi::to_wide (rhs2), UNSIGNED);\n> +\n> +             widest_int shifted\n> +               = wi::lrshift (info->needed_bits, shift_count);\n> +\n> +             if (shifted == 0)\n> +               {\n> +                 if (dump_file && (dump_flags & TDF_DETAILS))\n> +                   {\n> +                     fprintf (dump_file, \"Eliding redundant shift in \");\n> +                     print_gimple_stmt (dump_file, assign, 0, TDF_SLIM);\n> +                   }\n> +\n> +                 prepare_change (lhs);\n> +                 gimple_stmt_iterator gsi = gsi_for_stmt (assign);\n> +                 gimple_assign_set_rhs_from_tree\n> +                   (&gsi, build_zero_cst (TREE_TYPE (lhs)));\n> +                 complete_change (assign);\n> +               }\n> +           }\n> +       }\n> +      break;\n> +\n>      default:\n>        break;\n>      }\n> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-1.c b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-1.c\n> new file mode 100644\n> index 00000000000..e46adce4bdb\n> --- /dev/null\n> +++ b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-1.c\n> @@ -0,0 +1,16 @@\n> +/* { dg-do compile } */\n> +/* { dg-additional-options \"-O -fdump-tree-backprop-details\" } */\n> +\n> +#include <stdbool.h>\n> +\n> +void use (unsigned);\n> +\n> +void\n> +src (bool c, unsigned a, unsigned b) {\n> +    unsigned s = c ? a & 24 : b & 25;\n> +    use(s & 8);\n> +    use(s & 16);\n> +}\n> +\n> +/* { dg-final { scan-tree-dump-not \"  s_8 = a_7(D) & 24;\" \"backprop\" } } */\n> +/* { dg-final { scan-tree-dump-not \"  s_6 = b_5(D) & 25;\" \"backprop\" } } */\n> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-2.c b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-2.c\n> new file mode 100644\n> index 00000000000..3a4af6b8a10\n> --- /dev/null\n> +++ b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-2.c\n> @@ -0,0 +1,29 @@\n> +/* { dg-do compile } */\n> +/* { dg-additional-options \"-O -fdump-tree-optimized\" } */\n> +\n> +int\n> +foo (int t)\n> +{\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +\n> +  return t;\n> +}\n> +\n> +/* { dg-final { scan-tree-dump \"4095\" \"optimized\" } } */\n> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-3.c b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-3.c\n> new file mode 100644\n> index 00000000000..d7b573edf88\n> --- /dev/null\n> +++ b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-3.c\n> @@ -0,0 +1,29 @@\n> +/* { dg-do compile { target bitint } } */\n> +/* { dg-additional-options \"-O -fdump-tree-optimized\" } */\n> +\n> +int\n> +foo (int t)\n> +{\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +  t += 3 + 3 * t;\n> +  t &= 0xFFF;\n> +\n> +  return t;\n> +}\n> +\n> +/* { dg-final { scan-tree-dump \"return\" \"optimized\" } } */\n> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-4.c b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-4.c\n> new file mode 100644\n> index 00000000000..7fcc90c7adf\n> --- /dev/null\n> +++ b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-4.c\n> @@ -0,0 +1,34 @@\n> +/* { dg-do compile } */\n> +/* { dg-additional-options \"-O -fdump-tree-backprop-details -std=gnu99\" } */\n> +\n> +void use (unsigned);\n> +\n> +void\n> +foo (unsigned x)\n> +{\n> +  unsigned a = x & 0xff;\n> +  unsigned b = a * 4;\n> +  use (b & 0x10);\n> +  use (b & 0xe0);\n> +}\n> +\n> +void\n> +bar (unsigned x)\n> +{\n> +  unsigned a = x & 0xff;\n> +  unsigned b = a / 3;\n> +  use (b & 0x3);\n> +  use (b & 0xc);\n> +}\n> +\n> +void\n> +baz (unsigned x)\n> +{\n> +  unsigned a = x & 0xffff;\n> +  unsigned a2 = a * 2;\n> +  unsigned b = a2 & 0xff;\n> +  use (b & 0x3);\n> +  use (b & 0xc);\n> +}\n> +\n> +/* { dg-final { scan-tree-dump-times \"Eliding redundant mask\" 3 \"backprop\" } } */\n> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-5.c b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-5.c\n> new file mode 100644\n> index 00000000000..7a0ab3ade7d\n> --- /dev/null\n> +++ b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-5.c\n> @@ -0,0 +1,39 @@\n> +/* { dg-do compile } */\n> +/* { dg-additional-options \"-O -fdump-tree-backprop-details -std=gnu99\" } */\n> +\n> +void use (unsigned);\n> +\n> +void\n> +foo (unsigned x)\n> +{\n> +  unsigned a = x & 0xff;\n> +  use (a & 0xf);\n> +  use (a);\n> +}\n> +\n> +void\n> +bar (unsigned x, unsigned y)\n> +{\n> +  unsigned a = x & 0xff;\n> +  unsigned b = a + y;\n> +  use (b & 0xf);\n> +}\n> +\n> +void\n> +baz (unsigned x, unsigned s)\n> +{\n> +  unsigned a = x & 0xff;\n> +  unsigned b = a << s;\n> +  use (b & 0xf);\n> +}\n> +\n> +unsigned\n> +baf (unsigned x, int n)\n> +{\n> +  unsigned a = x & 0xff;\n> +  for (int i = 0; i < n; i++)\n> +    a = (a + 1) & 0xff;\n> +  return a;\n> +}\n> +\n> +/* { dg-final { scan-tree-dump-not \"Eliding redundant mask\" \"backprop\" } } */\n> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-6.c b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-6.c\n> new file mode 100644\n> index 00000000000..6cedb819c81\n> --- /dev/null\n> +++ b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-6.c\n> @@ -0,0 +1,18 @@\n> +/* { dg-do compile } */\n> +/* { dg-additional-options \"-O -fdump-tree-backprop-details -std=gnu99\" } */\n> +\n> +void use (unsigned);\n> +\n> +void\n> +f_phi (int c, unsigned x, unsigned y)\n> +{\n> +  unsigned t;\n> +  if (c)\n> +    t = x & 0xff;\n> +  else\n> +    t = y & 0xff;\n> +  use (t & 0x3);\n> +  use (t & 0xc);\n> +}\n> +\n> +/* { dg-final { scan-tree-dump-times \"Eliding redundant mask\" 2 \"backprop\" } } */\n> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-7.c b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-7.c\n> new file mode 100644\n> index 00000000000..795e461160f\n> --- /dev/null\n> +++ b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-7.c\n> @@ -0,0 +1,41 @@\n> +/* { dg-do compile } */\n> +/* { dg-additional-options \"-O -fdump-tree-backprop-details -std=gnu99\" } */\n> +\n> +void use (unsigned);\n> +\n> +void\n> +foo (unsigned x)\n> +{\n> +  unsigned a = x | 0xff00;\n> +  unsigned b = a * 2;\n> +  use (b & 0x3);\n> +  use (b & 0xc);\n> +}\n> +\n> +void\n> +bar (unsigned x)\n> +{\n> +  unsigned a = x ^ 0xff00;\n> +  unsigned b = a * 2;\n> +  use (b & 0x3);\n> +  use (b & 0xc);\n> +}\n> +\n> +void\n> +baz (unsigned x)\n> +{\n> +  unsigned a = x | 0x18;\n> +  use (a & 0x3);\n> +  use (a & 0xc);\n> +}\n> +\n> +void\n> +baf (unsigned x)\n> +{\n> +  unsigned a = x ^ 0x18;\n> +  use (a & 0x3);\n> +  use (a & 0xc);\n> +}\n> +\n> +/* foo and bar can be simplified by eliding the IOR.  baz and baf can't.  */\n> +/* { dg-final { scan-tree-dump-times \"Eliding redundant\" 2 \"backprop\" } } */\n> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-8.c b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-8.c\n> new file mode 100644\n> index 00000000000..3f66c4f84a6\n> --- /dev/null\n> +++ b/gcc/testsuite/gcc.dg/tree-ssa/backprop-bits-8.c\n> @@ -0,0 +1,31 @@\n> +/* { dg-do compile } */\n> +/* { dg-additional-options \"-O -fdump-tree-backprop-details -std=gnu99\" } */\n> +\n> +void use (unsigned);\n> +\n> +void\n> +foo (unsigned x)\n> +{\n> +  unsigned b = x + 0xff00;\n> +  use (b & 0x1);\n> +  use (b & 0xe);\n> +}\n> +\n> +void\n> +bar (unsigned x, unsigned y)\n> +{\n> +  unsigned m = y & 0xFF00;\n> +  unsigned b = x - m;\n> +  use (b & 0xf);\n> +  use (b & 0xf0);\n> +}\n> +\n> +void\n> +baz (unsigned x)\n> +{\n> +  unsigned a = x << 8;\n> +  unsigned b = a / 3;\n> +  use (b & 0x3);\n> +}\n> +\n> +/* { dg-final { scan-tree-dump-times \"Eliding redundant\" 3 \"backprop\" } } */\n> --\n> 2.53.0","headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256\n header.s=qcppdkim1 header.b=flQY7kqb;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n header.a=rsa-sha256 header.s=google header.b=WklRDoEk;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=38.145.34.32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256\n header.s=qcppdkim1 header.b=flQY7kqb;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com\n header.a=rsa-sha256 header.s=google header.b=WklRDoEk","sourceware.org; dmarc=none (p=none dis=none)\n header.from=oss.qualcomm.com","sourceware.org;\n spf=pass smtp.mailfrom=oss.qualcomm.com","server2.sourceware.org;\n arc=pass smtp.remote-ip=205.220.168.131"],"Received":["from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g60kc3xtVz1yHZ\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 01 May 2026 02:59:03 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 4C64E436A06B\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 16:59:01 +0000 (GMT)","from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com\n [205.220.168.131])\n by sourceware.org (Postfix) with ESMTPS id D62B84BB3BA8\n for <gcc-patches@gcc.gnu.org>; Thu, 30 Apr 2026 16:58:27 +0000 (GMT)","from pps.filterd (m0279863.ppops.net [127.0.0.1])\n by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id\n 63UE6j8c3729448\n for <gcc-patches@gcc.gnu.org>; Thu, 30 Apr 2026 16:58:26 GMT","from mail-dy1-f198.google.com (mail-dy1-f198.google.com\n [74.125.82.198])\n by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4duy1wbdqx-1\n (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT)\n for <gcc-patches@gcc.gnu.org>; Thu, 30 Apr 2026 16:58:26 +0000 (GMT)","by mail-dy1-f198.google.com with SMTP id\n 5a478bee46e88-2ddd8ef5343so1186988eec.1\n for <gcc-patches@gcc.gnu.org>; Thu, 30 Apr 2026 09:58:26 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 4C64E436A06B","OpenDKIM Filter v2.11.0 sourceware.org D62B84BB3BA8"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org D62B84BB3BA8","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org D62B84BB3BA8","ARC-Seal":["i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1777568308; cv=pass;\n b=XiBihaROnDZKqFPkyAhhCsrYUkgzx/7UmYtvUXyPg4DbOCek9kKlF/qOvo8SltyqRDCxVowuc9qJ2qQNsFm0TW1TQ8R3N3S+0IOeLEwaVyRFXpK+rudFfXTgrwtRC5GxXf7mLSZ7QTE2OFWuiRbX6ylnIBK/oZCgN+DSXKGn/98=","i=1; a=rsa-sha256; t=1777568306; cv=none;\n d=google.com; s=arc-20240605;\n b=SeqSLNofd+K1cNomPqOI6+M2fJxKWh6XzhoBNNfrcJiFpY4CDfGH9OD0MKs2JBfG1K\n FXQ5Osgefal4Rnj2t4IlQ532kg9QUHaJsFl461GHKMI+ZNezo8l6GqKbKaq8QM5RVMbV\n 0QbdsBL5mI4X85yPPiQtQM1EfNdaSSoWAlMVqr/KWgAVPpF34ggIQAoULIciYp3k/4ii\n cP1j/iIPZtwGN1TZFa1oV5rYA2X1fbdbdb9oI3DnmefoVio6OqpEpvo2EzXJWsUDcAz7\n UwL6OQXSN9glKl06diDOSqxfkicfVMfTzckm5wafuqBhQbBNO7ZFfrnRJ2vVxQyLv628\n /iEQ=="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777568308; c=relaxed/simple;\n bh=Mz3DT/Kkp6nOTTvhDDiyxYH7D/KhKKMmq3s8SiZidYg=;\n h=DKIM-Signature:DKIM-Signature:MIME-Version:From:Date:Message-ID:\n Subject:To;\n b=D+BR89eE+xaeFUApJqn4kig5qpK5VwLTJ+Nh8uofDqhXITUkuV9e21ambwRf4DxRA4D1YFpQFV5VLLYQ8CS7SyYrGR997rQzAFzpY3mmNG1isyTF1Ra0FQ+iEOxOcIXeOeCR960FeJ+OGHncKEO8qJC6phVuSv6xgHhMuZDUlzA=","i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:dkim-signature;\n bh=smlXDi/A0LQwdDeQ+tssDQ60zCpWyTpStkld/G7GnDI=;\n fh=cX2EtZ1nEIyVN9dS491c9oD70ocZUF2Eif1SLfrtea0=;\n b=NO17zX+JO9ePmzfyMqrhg6YgSBNzaUJdbGLuGKaL3jTYI5Zd3JFGTZavzRsd7Or2IS\n /Rs6Lw8E6dj/PvR6JK1HR/ku/3AjMVtmAB0wP8HQdJwq3tz0NFpV4aMu5bE5ssfqM8fb\n aZYsUcpsfSNBxzXYS9/ROeQAKpltz7q2Q+Oh9pEmTcGLc5HJkxwcmlElS+058xHgfAyv\n xZTxJ8i23LsoFU9r6+E0YXrbAhtPJpGyoyOgx5/6zyqBnvfT4StR1NSE1LPbTk40RN8K\n wWmJ8SXNxvl9pzu05pUHBQYGpuvFxan+muKd2mb//pd1c4lDkhgsXK6CHWcIDA7nX9x4\n 1g8A==; darn=gcc.gnu.org"],"ARC-Authentication-Results":["i=2; server2.sourceware.org","i=1; mx.google.com; arc=none"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h=\n cc:content-transfer-encoding:content-type:date:from:in-reply-to\n :message-id:mime-version:references:subject:to; s=qcppdkim1; bh=\n smlXDi/A0LQwdDeQ+tssDQ60zCpWyTpStkld/G7GnDI=; b=flQY7kqbT0IfrlEX\n HiNsY/+gP3kuDy37uInOZF/lZj2q6dqgp8Dqqj/lOTyUCr2KX71lF74kSpoEJsow\n uzSWupraZPlFtL5vMnD5dVVVvEYvg5V25nNAF1Dp92YkEqfqoJBD7rNhfgCkQRuq\n x32Ad966ZPbJZT3DGjA7rIhnk+TBXg1tVJMqJjGTDizi5q0C4pycFONDQ4KuzH7m\n xg1fVx/woMNeIOMpYcBwFi5O+FIJ/S6FBzOrLux75VHBuoW1PS8OXwuyEdAjQQRF\n Tfnb6t0bRXu8zvflTPEMoZLzy/367A5guiKkhi+MCbCUAcBqhcFdp31c1HRZ/IAN\n WxsqIw==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=oss.qualcomm.com; s=google; t=1777568306; x=1778173106; darn=gcc.gnu.org;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:from:to:cc:subject:date\n :message-id:reply-to;\n bh=smlXDi/A0LQwdDeQ+tssDQ60zCpWyTpStkld/G7GnDI=;\n b=WklRDoEkztzeGSy6LR9kfrFXmgYUrTtlTwnM31nxTfjvjfe313D9tRgDwBMjDWXl5A\n hdKA9sQcp8E02Z6YCS8N5YoQUkkHwLh7WjIdVTv5vnz9BtY2s8OgMp9dffWfO+VoIBSJ\n uk8ZFZglvSJDiwuRNwa1sE6wPROf79nmiWVCS53SRhqbXVbtd7C968zSuuUsX7djW3Co\n LYxIV1V76181u0IjZjf9GHzg28ad+JTXtYJWiGu8Z5j2o61kuXsu3CVWXsNiQROxTlYX\n xsxx+j8ip9zNGCo1mpqLXeJW4AWDIji2rx0TVZoQ+vZS8I59rU/98nr85RSt65AGTFaG\n sQng=="],"X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777568306; x=1778173106;\n h=content-transfer-encoding:cc:to:subject:message-id:date:from\n :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=smlXDi/A0LQwdDeQ+tssDQ60zCpWyTpStkld/G7GnDI=;\n b=cfueWZpKk6Imv1EAUrC8cnFFHHgEIKufHIorxBx8mDw+WaR0jO8Ki8MkfRMwZZoqc0\n 8t4NWR0NKFBLjME4xLxz7miX/c38P8AeddRmE+QI+3qqSr3OpzEFI1dFihf6fW7I73sc\n x3U1kxbyh6y1AIg8T4jMUNGJAgM4G7C6vO+n/4Zgnpz4eS1rdSovyVQuZeJePBqslPIj\n Jk5AE3N6tsSvz4x8VreOxy/a2b6T9iZBwIGysT6i59WEh6mF7hk18ZA0ktnyDFkENnd8\n uifeAHtACAC8H16FModNwBsw0nJfOumfn88AqknxIgJgW0WAmHWWnveCWcH5CQUdZUMq\n FYYA==","X-Gm-Message-State":"AOJu0Yx3SXQWa6gYq4LlMQUoMAe2yamaN/DjlnPR/ejEu9wFqGBqz+4x\n j2LjGJkmTPtotkD25IquxAhhFwMJkWhKF1/JVsEwg0qOPJullif1aDfenM8nRjBeUFzT8J96uMZ\n /wpyDRAF1kisbGedtDleIxLCQJhfyOJDljwjJUrDLUEN5uDXmll17wM9TBM3fGpX1NY8HwOfJhf\n ydoQtN98dP89rCjVnr3yIfgFEqpnRo0ad9G70=","X-Gm-Gg":"AeBDies5sRLe5voRXxW1tMF2mn5ixeUeIhmL/EIZZhwOb+wO9JelRTxxJRLHOZXT0ag\n IW6n/ekFC1LYHrGpzQEv50Opg2O5pgzlpIso30Mq/ORJaJO/V5TwpZ6MPgMrE4AN6zqEevhY/kL\n D3K3r6hP7D4aMYfGPr9TL+GA8P64ZppJwz4Ly35rJ8minuu5qPudb/rANc8G5C5THccCe8MBbYQ\n dZTZXlJ0CXUsg==","X-Received":["by 2002:a05:7300:e2cb:b0:2ed:e14:42e7 with SMTP id\n 5a478bee46e88-2ed3fe5adddmr1827568eec.32.1777568305284;\n Thu, 30 Apr 2026 09:58:25 -0700 (PDT)","by 2002:a05:7300:e2cb:b0:2ed:e14:42e7 with SMTP id\n 5a478bee46e88-2ed3fe5adddmr1827537eec.32.1777568304271; Thu, 30 Apr 2026\n 09:58:24 -0700 (PDT)"],"MIME-Version":"1.0","References":"<DI6KI7UV67P0.34JJS8EFC64T9@gmail.com>","In-Reply-To":"<DI6KI7UV67P0.34JJS8EFC64T9@gmail.com>","From":"Andrew Pinski <andrew.pinski@oss.qualcomm.com>","Date":"Thu, 30 Apr 2026 09:58:13 -0700","X-Gm-Features":"AVHnY4IU3Rjmr5yy1ctDVxF3jpjZGF8WtWG4JxUUpT3xuVeyD2Bw5kewfqVUNC0","Message-ID":"\n <CALvbMcCYamEkZ+2P5T12A2j0XQFZ4T4xpKC0fiNkDhXL_sHoKw@mail.gmail.com>","Subject":"Re: [PATCH] backprop: Add demand-bit handling. [PR113487]","To":"Robin Dapp <rdapp.gcc@gmail.com>","Cc":"gcc-patches <gcc-patches@gcc.gnu.org>,\n Richard Sandiford <rdsandiford@googlemail.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","X-Proofpoint-GUID":"aOKVsuOjX1GZpWHj6nhjCsEcNpoEhvI7","X-Proofpoint-ORIG-GUID":"aOKVsuOjX1GZpWHj6nhjCsEcNpoEhvI7","X-Authority-Analysis":"v=2.4 cv=DPy/JSNb c=1 sm=1 tr=0 ts=69f38a32 cx=c_pps\n a=wEP8DlPgTf/vqF+yE6f9lg==:117 a=IkcTkHD0fZMA:10 a=A5OVakUREuEA:10\n a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22\n a=yOCtJkima9RkubShWh1s:22 a=NEAV23lmAAAA:8 a=pGLkceISAAAA:8\n a=p1TwysC7tHOqP943EbcA:9 a=QEXdDO2ut3YA:10 a=bBxd6f-gb0O0v-kibOvt:22","X-Proofpoint-Spam-Details-Enc":"AW1haW4tMjYwNDMwMDE3NSBTYWx0ZWRfX3JvKorGBcVZu\n dGdqUaIt8cyqjUSrewHUoAvawyOOGKiRfSkiWDCaxQwvTx0C3CoSj1pC5WJ1CQX7ghlGsJqem/+\n dQ2XhBMGqK/Nx/xmZ2w3qgVgbztm0cPUz5UMqkP7ppkuQ9R9Ow4kfJ3MMXdYs+wvePaAP5UGi65\n pw5kzbYJKw7CaN0Y7yZk2IzmK7d8W7xF4+FvKP5eUgJHJsFnPBpgMJZLyOI9IQYr4Hh2Ksq5RBm\n qSXqZxmB7pXWcFZ01ZQIhfP6FcZSG2yTbtS4ZQRgS61cv9jiaO95OSbOGYdYfYFNm2gdVjO6xtG\n ElK0LLvLxSfNwTpbfWmSzEF+3yJwUXFklV6U7Mv/6HxSOMODQW5ZeJ7YXXaNctdBpVDt92sY09T\n rV7wd7ckkUtR8TkOoPedQjDlqS7hGt9zF8EBLxSQF8QShcqCmRLCyL8AYzqcK6voTIIDeJ1nLyi\n 8IIOz8zZmUKi8blQrPA==","X-Proofpoint-Virus-Version":"vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49\n definitions=2026-04-30_05,2026-04-30_02,2025-10-01_01","X-Proofpoint-Spam-Details":"rule=outbound_notspam policy=outbound score=0\n clxscore=1015 priorityscore=1501 malwarescore=0 spamscore=0 bulkscore=0\n lowpriorityscore=0 adultscore=0 impostorscore=0 phishscore=0 suspectscore=0\n classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0\n reason=mlx scancount=1 engine=8.22.0-2604200000 definitions=main-2604300175","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"}}]