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)

Reply via email to