https://gcc.gnu.org/g:fbbe414895c6450ff3e282ed45c2b8306bc1f67e

commit r17-4985-gfbbe414895c6450ff3e282ed45c2b8306bc1f67e
Author: Kyrylo Tkachov <[email protected]>
Date:   Tue Oct 6 15:45:44 2026 +0200

    genmatch: Avoid replicating patterns over unused for-iterators
    
    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.  This is always a match.pd authoring
    mistake: such a pattern should be moved outside the enclosing for-loop.
    
    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, emit a diagnostic and emit only a single copy with
    j=0 operator values.
    
    Fix the instance that motivated this: the (for lop ...) pattern inside
    (for op ...) at match.pd:6580 does not use op.  Move it outside.
    
    gcc/ChangeLog:
    
            * genmatch.cc (lower_for): Emit a diagnostic and skip replicated
            substitutions when no for-level iterator appears in the pattern.
            * match.pd: Move the (for lop ...) vec_cond pattern outside the
            enclosing (for op ...).
    
    Signed-off-by: Kyrylo Tkachov <[email protected]>

Diff:
---
 gcc/genmatch.cc | 12 +++++++++++-
 gcc/match.pd    | 18 +++++++++---------
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
index a67426b6313c..6f3f3c670baa 100644
--- a/gcc/genmatch.cc
+++ b/gcc/genmatch.cc
@@ -2446,7 +2446,17 @@ 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])));
+         if (!any_id_used)
+           warning_at (s->match->location,
+                       "pattern does not use any operator from the enclosing"
+                       " for; move it outside");
+         for (unsigned j = 0; j < (any_id_used ? max_n_opers : 1u); ++j)
            {
              operand *match_op = s->match;
              operand *result_op = s->result;
diff --git a/gcc/match.pd b/gcc/match.pd
index 833ee23b8fcc..0a4f7b718b46 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6642,15 +6642,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
               && !expand_vec_cond_expr_p (TREE_TYPE (@1), TREE_TYPE (@0)))))
    (vec_cond @0 (op!:type @1 @3) (op!:type @2 @4))))
 
-/* (@0 ? @2 : @3) lop (@1 ? @2 : @3)  -->  (@0 lop @1) ? @2 : @3.  */
-(for lop (bit_and bit_ior bit_xor)
-   (simplify
-   (lop
-      (vec_cond @0 integer_minus_onep@2 integer_zerop@3)
-      (vec_cond @1 @2 @3))
-      (if (target_supports_op_p (TREE_TYPE (@0), lop, optab_vector))
-   (vec_cond (lop @0 @1) @2 @3))))
-
 /* (c ? a : b) op d  -->  c ? (a op d) : (b op d) */
  (simplify
   (op (vec_cond:s @0 @1 @2) @3)
@@ -6671,6 +6662,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
               && !expand_vec_cond_expr_p (TREE_TYPE (@1), TREE_TYPE (@0)))))
    (vec_cond @0 (op!:type @3 @1) (op!:type @3 @2)))))
 
+/* (@0 ? @2 : @3) lop (@1 ? @2 : @3)  -->  (@0 lop @1) ? @2 : @3.  */
+(for lop (bit_and bit_ior bit_xor)
+   (simplify
+   (lop
+      (vec_cond @0 integer_minus_onep@2 integer_zerop@3)
+      (vec_cond @1 @2 @3))
+      (if (target_supports_op_p (TREE_TYPE (@0), lop, optab_vector))
+   (vec_cond (lop @0 @1) @2 @3))))
+
 /* If we have a "if a bit is not set, set it" case,
    just set the bit all the time (PR 64567).  Note that
    this does not work if we're checking for more than one

Reply via email to