https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67351
Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2015-08-26
     Ever confirmed|0                           |1

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
Yes, << N >> N can be converted (but only for unsigned right shift or in VRP
with range information).  Convert the following fold-const.c code to match.pd:

      /* Transform (x >> c) << c into x & (-1<<c), or transform (x << c) >> c
         into x & ((unsigned)-1 >> c) for unsigned types.  */
      if (((code == LSHIFT_EXPR && TREE_CODE (arg0) == RSHIFT_EXPR)
           || (TYPE_UNSIGNED (type)
               && code == RSHIFT_EXPR && TREE_CODE (arg0) == LSHIFT_EXPR))
          && tree_fits_uhwi_p (arg1)
          && tree_to_uhwi (arg1) < prec
          && tree_fits_uhwi_p (TREE_OPERAND (arg0, 1))
          && tree_to_uhwi (TREE_OPERAND (arg0, 1)) < prec)
        { 
          HOST_WIDE_INT low0 = tree_to_uhwi (TREE_OPERAND (arg0, 1));
          HOST_WIDE_INT low1 = tree_to_uhwi (arg1);
          tree lshift;
          tree arg00;

          if (low0 == low1)
            { 
              arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));

              lshift = build_minus_one_cst (type);
              lshift = const_binop (code, lshift, arg1);

              return fold_build2_loc (loc, BIT_AND_EXPR, type, arg00, lshift);
            }
        }

Reply via email to