From: Kyrylo Tkachov <[email protected]>

lower_for replicates each pattern once per operator of each for-level,
substituting the operator into the match and result.  When a pattern
does not reference any of the for-level iterators in either its match
or result, every substituted copy is structurally identical, producing
dead leaves in the decision tree.

Since f6eb8291e1c (PR119196, 2025-07-09), match.pd:6638 has a
(for lop ...) pattern nested inside a (for op ...) whose 34-operator
list it does not use.  lower_for therefore emits 34 identical copies of
each of the three lop alternatives per GIMPLE and GENERIC IL.

Before proceeding through the operator substitution loop, check whether
any id in the current for-level appears in the pattern's match or
result.  If none do, a single copy with j=0 operator values suffices
and the remaining max_n_opers-1 iterations are skipped.

Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?
Thanks,
Kyrill

gcc/ChangeLog:

        * genmatch.cc (lower_for): Skip replicated substitutions when no
        for-level iterator appears in the pattern.

Signed-off-by: Kyrylo Tkachov <[email protected]>
---
 gcc/genmatch.cc | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
index 9bb7cbbb427..1d53283e094 100644
--- a/gcc/genmatch.cc
+++ b/gcc/genmatch.cc
@@ -2433,7 +2433,13 @@ lower_for (simplify *sin, vec<simplify *>& simplifiers)
       for (unsigned si = worklist_start; si < worklist_end; ++si)
        {
          simplify *s = worklist[si];
-         for (unsigned j = 0; j < max_n_opers; ++j)
+         /* If none of the for-level ids appear in this pattern's match or
+            result, all operator substitutions are no-ops.  Emit one copy.  */
+         bool any_id_used = false;
+         for (unsigned i = 0; i < n_ids && !any_id_used; ++i)
+           any_id_used = (contains_id (s->match, ids[i])
+                          || (s->result && contains_id (s->result, ids[i])));
+         for (unsigned j = 0; j < (any_id_used ? max_n_opers : 1u); ++j)
            {
              operand *match_op = s->match;
              operand *result_op = s->result;
-- 
2.50.1 (Apple Git-155)

Reply via email to