Commit e3d3cfb4 by Kyrylo Tkachov Committed by Kyrylo Tkachov

re PR tree-optimization/58088 (ICE in gcc.c)

[gcc/]
2013-09-17  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

	PR tree-optimization/58088
	* fold-const.c (mask_with_trailing_zeros): New function.
	(fold_binary_loc): Make sure we don't recurse infinitely
	when the X in (X & C1) | C2 is a tree of the form (Y * K1) & K2.
	Use mask_with_trailing_zeros where appropriate.

[gcc/testsuite]
2013-09-17  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

	PR tree-optimization/58088
	* gcc.c-torture/compile/pr58088.c: New test.

From-SVN: r202652
parent 4fce5f02
2013-09-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR tree-optimization/58088
* fold-const.c (mask_with_trailing_zeros): New function.
(fold_binary_loc): Make sure we don't recurse infinitely
when the X in (X & C1) | C2 is a tree of the form (Y * K1) & K2.
Use mask_with_trailing_zeros where appropriate.
2013-09-17 Yuri Rumyantsev <ysrumyan@gmail.com> 2013-09-17 Yuri Rumyantsev <ysrumyan@gmail.com>
* config/i386/i386.c (distance_agu_use_in_bb) : Proper initialization * config/i386/i386.c (distance_agu_use_in_bb) : Proper initialization
......
...@@ -9942,6 +9942,24 @@ exact_inverse (tree type, tree cst) ...@@ -9942,6 +9942,24 @@ exact_inverse (tree type, tree cst)
} }
} }
/* Mask out the tz least significant bits of X of type TYPE where
tz is the number of trailing zeroes in Y. */
static double_int
mask_with_tz (tree type, double_int x, double_int y)
{
int tz = y.trailing_zeros ();
if (tz > 0)
{
double_int mask;
mask = ~double_int::mask (tz);
mask = mask.ext (TYPE_PRECISION (type), TYPE_UNSIGNED (type));
return mask & x;
}
return x;
}
/* Fold a binary expression of code CODE and type TYPE with operands /* Fold a binary expression of code CODE and type TYPE with operands
OP0 and OP1. LOC is the location of the resulting expression. OP0 and OP1. LOC is the location of the resulting expression.
Return the folded expression if folding is successful. Otherwise, Return the folded expression if folding is successful. Otherwise,
...@@ -11266,6 +11284,8 @@ fold_binary_loc (location_t loc, ...@@ -11266,6 +11284,8 @@ fold_binary_loc (location_t loc,
{ {
double_int c1, c2, c3, msk; double_int c1, c2, c3, msk;
int width = TYPE_PRECISION (type), w; int width = TYPE_PRECISION (type), w;
bool try_simplify = true;
c1 = tree_to_double_int (TREE_OPERAND (arg0, 1)); c1 = tree_to_double_int (TREE_OPERAND (arg0, 1));
c2 = tree_to_double_int (arg1); c2 = tree_to_double_int (arg1);
...@@ -11300,7 +11320,21 @@ fold_binary_loc (location_t loc, ...@@ -11300,7 +11320,21 @@ fold_binary_loc (location_t loc,
break; break;
} }
} }
if (c3 != c1)
/* 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)
return fold_build2_loc (loc, BIT_IOR_EXPR, type, return fold_build2_loc (loc, BIT_IOR_EXPR, type,
fold_build2_loc (loc, BIT_AND_EXPR, type, fold_build2_loc (loc, BIT_AND_EXPR, type,
TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 0),
...@@ -11690,22 +11724,16 @@ fold_binary_loc (location_t loc, ...@@ -11690,22 +11724,16 @@ fold_binary_loc (location_t loc,
&& TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg0) == MULT_EXPR
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST) && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
{ {
int arg1tz double_int masked
= tree_to_double_int (TREE_OPERAND (arg0, 1)).trailing_zeros (); = mask_with_tz (type, tree_to_double_int (arg1),
if (arg1tz > 0) tree_to_double_int (TREE_OPERAND (arg0, 1)));
{
double_int arg1mask, masked; if (masked.is_zero ())
arg1mask = ~double_int::mask (arg1tz); return omit_two_operands_loc (loc, type, build_zero_cst (type),
arg1mask = arg1mask.ext (TYPE_PRECISION (type), arg0, arg1);
TYPE_UNSIGNED (type)); else if (masked != tree_to_double_int (arg1))
masked = arg1mask & tree_to_double_int (arg1); return fold_build2_loc (loc, code, type, op0,
if (masked.is_zero ()) double_int_to_tree (type, masked));
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));
}
} }
/* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M, /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
......
2013-09-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR tree-optimization/58088
* gcc.c-torture/compile/pr58088.c: New test.
2013-09-17 Nick Clifton <nickc@redhat.com> 2013-09-17 Nick Clifton <nickc@redhat.com>
* lib/target-supports.exp (check_effective_target_trampolines): * lib/target-supports.exp (check_effective_target_trampolines):
......
int
bar (int i)
{
return 1 | ((i * 2) & 254);
}
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