On February 13, 2018 6:51:29 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >On the following testcase, we recurse infinitely, because >we have float re-association enabled, but also rounding-math, so >we try to optimize (cst1 + cst2) + cst3 as (cst2 + cst3) + cst1 >but (cst2 + cst3) doesn't simplify and we try again and optimize >it as (cst3 + cst1) + cst2 and then (cst1 + cst2) + cst3 and so on >forever. If @0 is not a CONSTANT_CLASS_P, there is not a problem, >if it is, the code just checks if we can actually simplify the >operation between cst2 and cst3 into a constant.
Is there a reason to try simplifying at all for constant @0? I'd rather not try to avoid all the complex code. Richard. >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > >2018-02-13 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/84334 > * match.pd ((A +- CST1) +- CST2 -> A + CST3): If A is > also a CONSTANT_CLASS_P, only optimize if we can fold the > operation between CST1 and CST2 into a constant. > > * gcc.dg/pr84334.c: New test. > >--- gcc/match.pd.jj 2018-02-13 09:33:31.000000000 +0100 >+++ gcc/match.pd 2018-02-13 12:14:08.108314686 +0100 >@@ -1733,9 +1733,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > CONSTANT_CLASS_P@2) > /* If one of the types wraps, use that one. */ > (if (!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_WRAPS (type)) >- (if (outer_op == PLUS_EXPR) >- (plus (view_convert @0) (inner_op @2 (view_convert @1))) >- (minus (view_convert @0) (neg_inner_op @2 (view_convert @1)))) >+ /* If all 3 captures are CONSTANT_CLASS_P, only optimize if we >+ can simplify @2 with @1 into a constant, otherwise we might recurse >+ forever. */ >+ (if (CONSTANT_CLASS_P (@0)) >+ (with { tree cst = fold_unary (VIEW_CONVERT_EXPR, type, @1); >+ if (cst && CONSTANT_CLASS_P (cst)) >+ cst = const_binop (outer_op == PLUS_EXPR >+ ? inner_op : neg_inner_op, type, >+ @2, cst); } >+ (if (cst) >+ (outer_op (view_convert @0) { cst; }))) >+ (if (outer_op == PLUS_EXPR) >+ (plus (view_convert @0) (inner_op @2 (view_convert @1))) >+ (minus (view_convert @0) (neg_inner_op @2 (view_convert @1))))) > (if (!ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) > || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))) > (if (outer_op == PLUS_EXPR) >--- gcc/testsuite/gcc.dg/pr84334.c.jj 2018-02-13 12:18:12.765463667 >+0100 >+++ gcc/testsuite/gcc.dg/pr84334.c 2018-02-13 11:36:56.019632428 +0100 >@@ -0,0 +1,12 @@ >+/* PR tree-optimization/84334 */ >+/* { dg-do compile } */ >+/* { dg-options "-Ofast -frounding-math" } */ >+ >+float >+foo (void) >+{ >+ float a = 9.999999974752427078783512115478515625e-7f; >+ float b = 1.999999994950485415756702423095703125e-6f; >+ float c = 4.999999873689375817775726318359375e-6f; >+ return a + b + c; >+} > > Jakub