[PATCH] Loop distribution improvements
Marc Glisse
marc.glisse@inria.fr
Fri Apr 5 21:00:00 GMT 2013
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.glisse@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
-------------- next part --------------
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);
More information about the Gcc-patches
mailing list