On Mon, 7 Sep 2026, [email protected] wrote: > From: Kyrylo Tkachov <[email protected]> > > genmatch can leave the iterators of a named match unexpanded. Code generation > emits COND_EXPR conditions in opcode switches. Overlapping delayed iterator > sets can then emit duplicate case labels.
Can you show an example pattern? > Substitute a group before decision-tree insertion when one of its iterators > occurs in a COND_EXPR condition. The existing eager path keeps the > substitutions aligned and lets the decision tree merge common concrete > operations. Other named matches keep delayed substitution. > > A reduced GIMPLE and GENERIC matcher with overlapping iterator sets fails to > compile before this change. Both forms compile after the change. > This is needed to accept the patterns in patch 3/3. > > Bootstrapped and tested on aarch64-none-linux-gnu. > > Ok for trunk? > Thanks, > Kyrill > > gcc/ChangeLog: > > * genmatch.cc (cond_expr_condition_contains_id): New function. > (lower_for): Expand iterators used in COND_EXPR conditions. > (lower): Update comment. > > Signed-off-by: Kyrylo Tkachov <[email protected]> > --- > gcc/genmatch.cc | 44 ++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 40 insertions(+), 4 deletions(-) > > diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc > index 1bc5875d7dd..c4bb1c12400 100644 > --- a/gcc/genmatch.cc > +++ b/gcc/genmatch.cc > @@ -2159,6 +2159,26 @@ contains_id (operand *o, user_id *id) > return false; > } > > +/* Return true if O contains a COND_EXPR condition that refers to ID. */ > + > +static bool > +cond_expr_condition_contains_id (operand *o, user_id *id) > +{ > + if (capture *c = dyn_cast <capture *> (o)) > + return c->what && cond_expr_condition_contains_id (c->what, id); > + > + if (expr *e = dyn_cast <expr *> (o)) > + { > + if (*e->operation == COND_EXPR && contains_id (e->ops[0], id)) > + return true; > + for (unsigned i = 0; i < e->ops.length (); ++i) > + if (cond_expr_condition_contains_id (e->ops[i], id)) > + return true; > + } > + > + return false; > +} > + > > /* In AST operand O replace operator ID with operator WITH. */ > > @@ -2304,9 +2324,24 @@ lower_for (simplify *sin, vec<simplify *>& simplifiers) > else > can_delay_subst = false; > } > - if (sin->kind == simplify::MATCH > - && can_delay_subst) > - continue; > + /* Code generation emits COND_EXPR conditions in opcode switches. > + Substitute iterators in these conditions before inserting the patterns > + into the decision tree. Overlapping iterator sets could otherwise > + emit duplicate case labels. */ > + if (sin->kind == simplify::MATCH && can_delay_subst) > + { > + for (unsigned si = worklist_start; > + si < worklist.length () && can_delay_subst; ++si) > + for (unsigned i = 0; i < n_ids; ++i) > + if (cond_expr_condition_contains_id (worklist[si]->match, > + ids[i])) > + { > + can_delay_subst = false; > + break; > + } > + if (can_delay_subst) > + continue; > + } > > unsigned worklist_end = worklist.length (); > for (unsigned si = worklist_start; si < worklist_end; ++si) > @@ -2374,7 +2409,8 @@ lower (vec<simplify *>& simplifiers, bool gimple) > /* Lower for needs to happen before lowering cond > to support (for cnd (cond vec_cond)). This is > safe as substitution delay does not happen for > - cond or vec_cond. */ > + cond or vec_cond, or for iterators used in a > + COND_EXPR condition. */ > out_simplifiers.truncate (0); > for (auto s: simplifiers) > lower_for (s, out_simplifiers); > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)
