> -----Original Message-----
> From: Andrea Pinski <[email protected]>
> Sent: 23 September 2026 18:47
> To: Tamar Christina <[email protected]>
> Cc: [email protected]; nd <[email protected]>; [email protected];
> [email protected]
> Subject: Re: [patch 9/14][isel]: form conditional vector compare IFNs
> 
> On Mon, Sep 14, 2026 at 2:32 AM Tamar Christina
> <[email protected]> wrote:
> >
> > This patch forms conditional vector compare IFNs during gimple isel.
> >
> > The match.pd rules recognize integer vector compare idioms where a
> compare is
> > guarded by another vector predicate.  gimple isel then lowers those idioms
> to
> > IFN_COND_VEC_CMP or IFN_COND_LEN_VEC_CMP when the target reports
> support for
> > the corresponding optab.  If the original compare was only used by the
> > converted statement, the patch removes that now-dead definition.
> >
> > The tests for this lowering are kept with the later AArch64 SVE expander
> > patch, since they require the SVE cond_vec_cmp target support added there.
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu,
> > arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> > -m32, -m64 and no issues.
> >
> > -O3, profiled, profiled -O3 and -O3 -LTO bootstrap tested and no issues.
> >
> >  Also SPECCPU 2017 and SPECCPU 2026 tested.
> >
> > OK for master?
> >
> > gcc/ChangeLog:
> >         * gimple-isel.cc (gimple_convert_conditional_compare): Declare.
> >         (gimple_convert_conditional_len_compare): Likewise.
> >         (maybe_duplicate_comparison): Fix comment.
> >         (gimple_expand_conditional_compare): New function.
> >         (pass_gimple_isel::execute): Use it.
> >         * match.pd (convert_conditional_compare): New match.
> >         (convert_conditional_len_compare): Likewise.
> >
> > ---
> > diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
> > index
> 1d346ee124ffdfdccf658ea79cc72cbf80240f81..9bd523cd81be541383ea9c9
> 62a9180565cea9f0d 100644
> > --- a/gcc/gimple-isel.cc
> > +++ b/gcc/gimple-isel.cc
> > @@ -327,8 +327,8 @@ maybe_duplicate_comparison (gassign *stmt,
> basic_block bb)
> >    tree lhs = gimple_assign_lhs (stmt);
> >    unsigned cnt = 0;
> >
> > -  /* This is should not be used for -O0 nor it is not useful
> > -     when ter is turned off. */
> > +  /* This should not be used for -O0 and is not useful when TER is turned
> > +     off.  */
> >    if (!optimize || !flag_tree_ter)
> >      return;
> >
> > @@ -376,6 +376,9 @@ maybe_duplicate_comparison (gassign *stmt,
> basic_block bb)
> >  extern bool gimple_nop_atomic_bit_test_and_p (tree, tree *,
> >                                               tree (*) (tree));
> >  extern bool gimple_nop_convert (tree, tree*, tree (*) (tree));
> > +extern bool gimple_convert_conditional_compare (tree, tree *, tree (*)
> (tree));
> > +extern bool gimple_convert_conditional_len_compare (tree, tree *,
> > +                                                  tree (*) (tree));
> >
> >  namespace {
> >
> > @@ -488,6 +491,74 @@ convert_atomic_bit_not (enum internal_fn fn,
> gimple *use_stmt,
> >    return use_stmt;
> >  }
> >
> > +/* Try to replace STMT with a conditional vector comparison internal
> function.
> > +   The generated matchers recognize the source patterns and capture the
> mask,
> > +   operands and original comparison SSA name.  If the original comparison 
> > is
> > +   used only by STMT, store its defining statement in *DEAD_CMP_DEF so
> that the
> > +   caller can remove it after replacing STMT.  */
> > +
> > +static gimple *
> > +gimple_expand_conditional_compare (gimple_stmt_iterator *gsi,
> > +                                  gassign **dead_cmp_def)
> > +{
> > +  gimple *stmt = gsi_stmt (*gsi);
> > +  *dead_cmp_def = nullptr;
> > +  tree lhs = gimple_get_lhs (stmt);
> > +
> > +  if (!lhs || TREE_CODE (lhs) != SSA_NAME)
> > +    return nullptr;
> > +
> > +  tree ops[6] = {};
> > +  location_t loc = gimple_location (stmt);
> > +  bool len_p = false;
> > +  if (!gimple_convert_conditional_compare (lhs, ops, nullptr)
> > +      && !gimple_convert_conditional_len_compare (lhs, ops, nullptr))
> > +    return nullptr;
> > +  len_p = ops[4] != NULL_TREE;
> > +
> > +  unsigned int cmp_opno = len_p ? 5 : 3;
> > +  tree cmp_name = ops[cmp_opno];
> > +  if (TREE_CODE (cmp_name) != SSA_NAME)
> > +    return nullptr;
> > +
> > +  gassign *cmp_def = dyn_cast<gassign *> (SSA_NAME_DEF_STMT
> (cmp_name));
> > +  if (!cmp_def)
> > +    return nullptr;
> > +
> > +  tree_code code = gimple_assign_rhs_code (cmp_def);
> > +  if (TREE_CODE_CLASS (code) != tcc_comparison)
> > +    return nullptr;
> > +
> > +  internal_fn ifn = len_p ? IFN_COND_LEN_VEC_CMP :
> IFN_COND_VEC_CMP;
> > +  bool supported_p
> > +    = (len_p
> > +       ? expand_cond_len_vec_cmp_p (code, ops[0], ops[1], ops[2],
> > +                                   ops[3], ops[4])
> > +       : expand_cond_vec_cmp_p (code, ops[0], ops[1], ops[2]));
> > +  if (!supported_p)
> > +    return nullptr;
> > +
> > +  auto_vec<tree, 6> args;
> > +  args.quick_push (build_int_cst (integer_type_node, code));
> > +  args.quick_push (ops[0]);
> > +  args.quick_push (ops[1]);
> > +  args.quick_push (ops[2]);
> > +  if (len_p)
> > +    {
> > +      args.quick_push (ops[3]);
> > +      args.quick_push (ops[4]);
> > +    }
> > +
> > +  gcall *call = gimple_build_call_internal_vec (ifn, args);
> > +  gimple_call_set_lhs (call, lhs);
> > +  gimple_set_location (call, loc);
> > +  use_operand_p use_p;
> > +  gimple *use_stmt;
> > +  if (single_imm_use (cmp_name, &use_p, &use_stmt) && use_stmt ==
> stmt)
> > +    *dead_cmp_def = cmp_def;
> > +  return call;
> > +}
> > +
> >  /* Optimize
> >       mask_2 = 1 << cnt_1;
> >       _4 = __atomic_fetch_or_* (ptr_6, mask_2, _3);
> > @@ -1369,6 +1440,20 @@ pass_gimple_isel::execute (struct function *fun)
> >           /* Give the target first try at replacing the instruction.  */
> >           cfg_changed |= targetm.instruction_selection (fun, &gsi);
> >
> > +         gimple *isel_stmt = NULL;
> > +         gassign *dead_cmp_def = NULL;
> > +         if (!gsi_end_p (gsi))
> > +           isel_stmt = gimple_expand_conditional_compare (&gsi,
> &dead_cmp_def);
> > +         if (isel_stmt)
> > +           {
> > +             gsi_replace (&gsi, isel_stmt, true);
> > +             if (dead_cmp_def)
> > +               {
> > +                 gimple_stmt_iterator cmp_gsi = gsi_for_stmt 
> > (dead_cmp_def);
> > +                 gsi_remove (&cmp_gsi, true);
> > +               }
> > +           }
> > +
> >           /* Pre-expand VEC_COND_EXPRs to .VCOND* internal function
> >              calls mapping to supported optabs.  */
> >           gimple *g = gimple_expand_vec_cond_expr (&gsi);
> > @@ -1411,4 +1496,3 @@ make_pass_gimple_isel (gcc::context *ctxt)
> >  {
> >    return new pass_gimple_isel (ctxt);
> >  }
> > -
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index
> c1aba410b66e38c947a4d52064fda1594934f297..db5038b7dccd030a09b6
> 7d5070a2ce2b74651184 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -13364,3 +13364,20 @@ and,
> >   (if (INTEGRAL_TYPE_P (type))
> >     (with { tree itype = TREE_TYPE (@2); }
> >      (convert (minus @2 (convert:itype @1))))))
> > +
> > +#if GIMPLE
> > +
> > +(for cmp (tcc_comparison)
> > + (match (convert_conditional_compare @0 @1 @2 @3)
> > +  (bit_and:c @0 (cmp@3 @1 @2))
> > +  (if (VECTOR_BOOLEAN_TYPE_P (type)
> > +       && !FLOAT_TYPE_P (TREE_TYPE (@1)))))
> 
> Just a minor thing here.  You don't need to use a for loop, you can
> use tcc_comparison directly.
> So this becomes:
> (match (convert_conditional_compare @0 @1 @2 @3)
>   (bit_and:c @0 (tcc_comparison@3 @1 @2))
>    (if (VECTOR_BOOLEAN_TYPE_P (type)
>         && !FLOAT_TYPE_P (TREE_TYPE (@1)))))
> 
> > +
> > +/* Transform .VCOND_MASK_LEN (a `cmp` b, {-1, ...}, {0, ...}, len, bias)
> > +   into cond_len_vec_cmp (cmp, mask, a, b, len, bias).  */
> > + (match (convert_conditional_len_compare @0 @1 @2 @3 @4 @5)
> > +  (IFN_VCOND_MASK_LEN @0 (cmp@5 @1 @2) integer_minus_onep
> integer_zerop @3 @4)
> > +  (if (VECTOR_BOOLEAN_TYPE_P (type)
> > +       && !FLOAT_TYPE_P (TREE_TYPE (@1))))))
> 
> Likewise.

Thanks, I learned something new :)

Cheers,
Tamar

> 
> Thanks,
> Andrea
> 
> > +
> > +#endif
> >
> >
> > --

Reply via email to