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
This commit is contained in:
Richard Biener 2014-05-05 09:23:31 +00:00 committed by Richard Biener
parent 33ecf1086a
commit 7e2c9f1434
4 changed files with 34 additions and 19 deletions

View File

@ -1,3 +1,10 @@
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

View File

@ -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,

View File

@ -1,3 +1,8 @@
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.

View File

@ -0,0 +1,8 @@
/* { dg-do compile } */
int main (void)
{
int a = 0;
unsigned b = (a * 64 & 192) | 63U;
return 0;
}