On Tue, 11 Mar 2025, Jakub Jelinek wrote:

> Hi!
> 
> The following testcase takes very long time to compile, because
> skip_simple_arithmetic decides to first call tree_invariant_p on
> the second argument (and indirectly recurse there).  I think before
> canonicalization of operands for commutative binary expressions
> (and for non-commutative ones always) it is pretty common that the
> first operand is a constant, something which tree_invariant_p handles
> immediately, so the following patch special cases that; I've added
> there a tree_invariant_p call too after the checks, while it is not
> really needed currently, tree_invariant_p has the same checks, I wanted
> to be prepared in case tree_invariant_p changes.  But if you think
> I should avoid it, I can drop it too.
> 
> This is just a partial fix, I think one can certainly construct a testcase
> which will still have horrible compile time complexity (but I've tried and
> haven't managed to do so), so perhaps we should just limit the recursion
> depth through skip_simple_arithmetic/tree_invariant_p with some defaulted
> argument.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Can you add a comment before the code?  OK with that change.

> 2025-03-11  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR c/119183
>       * tree.cc (skip_simple_arithmetic): If first operand of binary
>       expr is TREE_CONSTANT or TREE_READONLY with no side-effects, call
>       tree_invariant_p on that operand first instead of on the second.
> 
>       * gcc.dg/pr119183.c: New test.
> 
> --- gcc/tree.cc.jj    2025-03-08 00:07:01.848908327 +0100
> +++ gcc/tree.cc       2025-03-10 17:04:48.630157371 +0100
> @@ -4105,7 +4105,12 @@ skip_simple_arithmetic (tree expr)
>       expr = TREE_OPERAND (expr, 0);
>        else if (BINARY_CLASS_P (expr))
>       {
> -       if (tree_invariant_p (TREE_OPERAND (expr, 1)))
> +       if ((TREE_CONSTANT (TREE_OPERAND (expr, 0))
> +            || (TREE_READONLY (TREE_OPERAND (expr, 0))
> +                && !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0))))
> +           && tree_invariant_p (TREE_OPERAND (expr, 0)))
> +         expr = TREE_OPERAND (expr, 1);
> +       else if (tree_invariant_p (TREE_OPERAND (expr, 1)))
>           expr = TREE_OPERAND (expr, 0);
>         else if (tree_invariant_p (TREE_OPERAND (expr, 0)))
>           expr = TREE_OPERAND (expr, 1);
> --- gcc/testsuite/gcc.dg/pr119183.c.jj        2025-03-10 17:48:57.839774108 
> +0100
> +++ gcc/testsuite/gcc.dg/pr119183.c   2025-03-10 17:48:22.960253026 +0100
> @@ -0,0 +1,12 @@
> +/* PR c/119183 */
> +/* { dg-do compile } */
> +
> +int foo (void);
> +#define A(x) (1.0f * (1.0f * (1.0f * (1.0f * (1.0f * (1.0f * (1.0f * (1.0f * 
> (x)))))))))
> +
> +float
> +bar (float r)
> +{
> +  r += A (A (A (A (A (A (A (A (foo ()))))))));
> +  return r;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to