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);