Commit 7e2c9f14 by Richard Biener Committed by Richard Biener

re PR middle-end/61010 (Infinite recursion in fold)

2014-05-05  Richard Biener  <rguenther@suse.de>

	PR middle-end/61010
	* fold-const.c (fold_binary_loc): Consistently avoid
	canonicalizing X & CST away from a CST that is the mask
	of a mode.

	* gcc.dg/torture/pr61010.c: New testcase.

From-SVN: r210066
parent 33ecf108
2014-05-05 Richard Biener <rguenther@suse.de>
PR middle-end/61010
* fold-const.c (fold_binary_loc): Consistently avoid
canonicalizing X & CST away from a CST that is the mask
of a mode.
2014-05-05 Jan-Benedict Glaw <jbglaw@lug-owl.de>
* config/picochip/picochip-protos.h (picochip_regno_nregs): Change
......
......@@ -11426,7 +11426,6 @@ fold_binary_loc (location_t loc,
{
double_int c1, c2, c3, msk;
int width = TYPE_PRECISION (type), w;
bool try_simplify = true;
c1 = tree_to_double_int (TREE_OPERAND (arg0, 1));
c2 = tree_to_double_int (arg1);
......@@ -11463,20 +11462,7 @@ fold_binary_loc (location_t loc,
}
}
/* If X is a tree of the form (Y * K1) & K2, this might conflict
with that optimization from the BIT_AND_EXPR optimizations.
This could end up in an infinite recursion. */
if (TREE_CODE (TREE_OPERAND (arg0, 0)) == MULT_EXPR
&& TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))
== INTEGER_CST)
{
tree t = TREE_OPERAND (TREE_OPERAND (arg0, 0), 1);
double_int masked = mask_with_tz (type, c3, tree_to_double_int (t));
try_simplify = (masked != c1);
}
if (try_simplify && c3 != c1)
if (c3 != c1)
return fold_build2_loc (loc, BIT_IOR_EXPR, type,
fold_build2_loc (loc, BIT_AND_EXPR, type,
TREE_OPERAND (arg0, 0),
......@@ -11866,16 +11852,25 @@ fold_binary_loc (location_t loc,
&& TREE_CODE (arg0) == MULT_EXPR
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
{
double_int darg1 = tree_to_double_int (arg1);
double_int masked
= mask_with_tz (type, tree_to_double_int (arg1),
= mask_with_tz (type, darg1,
tree_to_double_int (TREE_OPERAND (arg0, 1)));
if (masked.is_zero ())
return omit_two_operands_loc (loc, type, build_zero_cst (type),
arg0, arg1);
else if (masked != tree_to_double_int (arg1))
return fold_build2_loc (loc, code, type, op0,
double_int_to_tree (type, masked));
else if (masked != darg1)
{
/* Avoid the transform if arg1 is a mask of some
mode which allows further optimizations. */
int pop = darg1.popcount ();
if (!(pop >= BITS_PER_UNIT
&& exact_log2 (pop) != -1
&& double_int::mask (pop) == darg1))
return fold_build2_loc (loc, code, type, op0,
double_int_to_tree (type, masked));
}
}
/* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
......
2014-05-05 Richard Biener <rguenther@suse.de>
PR middle-end/61010
* gcc.dg/torture/pr61010.c: New testcase.
2014-05-05 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* gcc.target/s390/leaf-profile.c: New testcase.
......
/* { dg-do compile } */
int main (void)
{
int a = 0;
unsigned b = (a * 64 & 192) | 63U;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment