https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119183

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Reduced testcase:
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;
}
No options are needed.
Given that I think binary expressions with a constant as first argument are
fairly common before we actually try to canonicalize expressions, I think a
patch like
--- 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);
could be useful and fixes this testcase.
But I'm afraid one can construct different testcases that will still be too
expensive, so wonder if there shouldn't be some depth argument passed through
tree_invariant_p/skip_simple_arithmetic and simply punt if it is too deep, we
don't want to avoid SAVE_EXPRs for too large subexpressions anyway, recomputing
them each time will be too expensive.  Or instead of depth compute expression
size say in number of subtrees and punt when it is larger than some constant.

Reply via email to