On Fri, 5 Apr 2013, Marc Glisse wrote:

Shouldn't we change integer_all_onesp to do what its name says and create a separate integer_minus_onep for the single place I could find where it would break, the folding of x * -1 ?

2013-04-05  Marc Glisse  <marc.gli...@inria.fr>

        * tree.c (integer_all_onesp) <COMPLEX_CST>: Test that both
        components are all 1s.
        (integer_minus_onep): New function.
        * tree.h (integer_minus_onep): Declare it.
        * fold-const.c (fold_binary_loc) <MULT_EXPR>: Test
        integer_minus_onep instead of integer_all_onesp.

It passes bootstrap+testsuite on x86_64-linux-gnu, but if someone else wants to go through the (not that long) list of integer_all_onesp to check for things that might break... I did not change places where the name "-1" might make more sense than "all 1s" but the type cannot be complex.

--
Marc Glisse
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 197532)
+++ gcc/fold-const.c    (working copy)
@@ -10802,21 +10802,21 @@ fold_binary_loc (location_t loc,
 
       if (! FLOAT_TYPE_P (type))
        {
          if (integer_zerop (arg1))
            return omit_one_operand_loc (loc, type, arg1, arg0);
          if (integer_onep (arg1))
            return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));
          /* Transform x * -1 into -x.  Make sure to do the negation
             on the original operand with conversions not stripped
             because we can only strip non-sign-changing conversions.  */
-         if (integer_all_onesp (arg1))
+         if (integer_minus_onep (arg1))
            return fold_convert_loc (loc, type, negate_expr (op0));
          /* Transform x * -C into -x * C if x is easily negatable.  */
          if (TREE_CODE (arg1) == INTEGER_CST
              && tree_int_cst_sgn (arg1) == -1
              && negate_expr_p (arg0)
              && (tem = negate_expr (arg1)) != arg1
              && !TREE_OVERFLOW (tem))
            return fold_build2_loc (loc, MULT_EXPR, type,
                                fold_convert_loc (loc, type,
                                                  negate_expr (arg0)),
Index: gcc/tree.c
===================================================================
--- gcc/tree.c  (revision 197532)
+++ gcc/tree.c  (working copy)
@@ -1774,33 +1774,33 @@ integer_onep (const_tree expr)
          if (!integer_onep (VECTOR_CST_ELT (expr, i)))
            return false;
        return true;
       }
     default:
       return false;
     }
 }
 
 /* Return 1 if EXPR is an integer containing all 1's in as much precision as
-   it contains.  Likewise for the corresponding complex constant.  */
+   it contains, or a complex or vector whose subparts are such integers.  */
 
 int
 integer_all_onesp (const_tree expr)
 {
   int prec;
   int uns;
 
   STRIP_NOPS (expr);
 
   if (TREE_CODE (expr) == COMPLEX_CST
       && integer_all_onesp (TREE_REALPART (expr))
-      && integer_zerop (TREE_IMAGPART (expr)))
+      && integer_all_onesp (TREE_IMAGPART (expr)))
     return 1;
 
   else if (TREE_CODE (expr) == VECTOR_CST)
     {
       unsigned i;
       for (i = 0; i < VECTOR_CST_NELTS (expr); ++i)
        if (!integer_all_onesp (VECTOR_CST_ELT (expr, i)))
          return 0;
       return 1;
     }
@@ -1832,20 +1832,34 @@ integer_all_onesp (const_tree expr)
       else
        high_value = ((HOST_WIDE_INT) 1 << shift_amount) - 1;
 
       return (TREE_INT_CST_LOW (expr) == ~(unsigned HOST_WIDE_INT) 0
              && TREE_INT_CST_HIGH (expr) == high_value);
     }
   else
     return TREE_INT_CST_LOW (expr) == ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
 }
 
+/* Return 1 if EXPR is the integer constant minus one.  */
+
+int
+integer_minus_onep (const_tree expr)
+{
+  STRIP_NOPS (expr);
+
+  if (TREE_CODE (expr) == COMPLEX_CST)
+    return (integer_all_onesp (TREE_REALPART (expr))
+           && integer_zerop (TREE_IMAGPART (expr)));
+  else
+    return integer_all_onesp (expr);
+}
+
 /* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only
    one bit on).  */
 
 int
 integer_pow2p (const_tree expr)
 {
   int prec;
   unsigned HOST_WIDE_INT high, low;
 
   STRIP_NOPS (expr);
Index: gcc/tree.h
===================================================================
--- gcc/tree.h  (revision 197532)
+++ gcc/tree.h  (working copy)
@@ -5303,20 +5303,25 @@ extern int integer_zerop (const_tree);
 
 /* integer_onep (tree x) is nonzero if X is an integer constant of value 1.  */
 
 extern int integer_onep (const_tree);
 
 /* integer_all_onesp (tree x) is nonzero if X is an integer constant
    all of whose significant bits are 1.  */
 
 extern int integer_all_onesp (const_tree);
 
+/* integer_minus_onep (tree x) is nonzero if X is an integer constant of
+   value -1.  */
+
+extern int integer_minus_onep (const_tree);
+
 /* integer_pow2p (tree x) is nonzero is X is an integer constant with
    exactly one bit 1.  */
 
 extern int integer_pow2p (const_tree);
 
 /* integer_nonzerop (tree x) is nonzero if X is an integer constant
    with a nonzero value.  */
 
 extern int integer_nonzerop (const_tree);
 

Reply via email to