On 09/09/13 10:56, Kyrylo Tkachov wrote:
[Resending, since I was away and not pinging it]
Hi all,
In PR58088 the constant folder goes into an infinite recursion and runs out of
stack space because of two conflicting optimisations:
(X * C1) C2 plays dirty when nested inside an IOR expression like so: ((X *
C1) C2) | C4. One can undo the other leading to an infinite recursion.
Thanks to Marek for finding the IOR case.
This patch fixes that by checking in the IOR case that the change to C2 will
not conflict with the AND case transformation. Example testcases in the PR on
bugzilla.
This affects both trunk and 4.8 and regresses and bootstraps cleanly on both.
Bootstrapped on x86_64-linux-gnu and tested arm-none-eabi on qemu.
Ok for trunk and 4.8?
Thanks,
Kyrill
2013-09-09 Kyrylo Tkachov kyrylo.tkac...@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-09 Kyrylo Tkachov kyrylo.tkac...@arm.com
PR tree-optimization/58088
* gcc.c-torture/compile/pr58088.c: New test.=
pr58088.patch
@@ -9942,6 +9942,22 @@ 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)
blank line between declarations and statements.
@@ -11266,6 +11282,7 @@ fold_binary_loc (location_t loc,
{
double_int c1, c2, c3, msk;
int width = TYPE_PRECISION (type), w;
+ bool valid = true;
c1 = tree_to_double_int (TREE_OPERAND (arg0, 1));
c2 = tree_to_double_int (arg1);
blank line after declarations before code body.
}
- if (c3 != c1)
+ /* If X is a tree of the form (Y * K1) K2, this might conflict
Should be a blank line before the comment as well
+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));
+ valid = masked != c1;
blank line before statements after declarations.
+ }
+
+ if (c3 != c1 valid)
'valid' should come before the comparison test. Furthermore, I think
'valid' is misleading; 'try_simplify' would be a more accurate
description of what the test is about.
OK with those changes.
R.