The (x >> c) << c folding has:

          && tree_fits_shwi_p (arg1)
          && TREE_INT_CST_LOW (arg1) < prec
          && tree_fits_shwi_p (TREE_OPERAND (arg0, 1))
          && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < prec)

At first glance the use of tree_fits_shwi_p rather than tree_fits_uhwi_p
made me think this allows negative shift counts, but of course TREE_INT_CST_LOW
is unsigned.  I think it'd be clearer to use tree_fits_uhwi_p instead.

Thanks,
Richard


gcc/
        * fold-const.c (fold_binary_loc): Use unsigned rather than signed
        HOST_WIDE_INTs when folding (x >> c) << c.

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    2013-11-19 10:53:54.965643984 +0000
+++ gcc/fold-const.c    2013-11-19 11:59:33.611252297 +0000
@@ -12676,13 +12676,13 @@ fold_binary_loc (location_t loc,
       if (((code == LSHIFT_EXPR && TREE_CODE (arg0) == RSHIFT_EXPR)
            || (TYPE_UNSIGNED (type)
               && code == RSHIFT_EXPR && TREE_CODE (arg0) == LSHIFT_EXPR))
-         && tree_fits_shwi_p (arg1)
-         && TREE_INT_CST_LOW (arg1) < prec
-         && tree_fits_shwi_p (TREE_OPERAND (arg0, 1))
-         && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < prec)
+         && 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_INT_CST_LOW (TREE_OPERAND (arg0, 1));
-         HOST_WIDE_INT low1 = TREE_INT_CST_LOW (arg1);
+         HOST_WIDE_INT low0 = tree_to_uhwi (TREE_OPERAND (arg0, 1));
+         HOST_WIDE_INT low1 = tree_to_uhwi (arg1);
          tree lshift;
          tree arg00;
 

Reply via email to