> -----Original Message----- > From: Tejas Belagod <[email protected]> > Sent: 28 November 2025 11:28 > To: [email protected] > Cc: Tejas Belagod <[email protected]>; Tamar Christina > <[email protected]>; [email protected] > Subject: [PATCH v3] AArch64: Flip svbool_t equal conditionals in ternary > operators. > > This patch flips == conditions: > > p == q ? s1 : s2; > > to > > p != q ? s2 : s1; > > where p and q are svbool_t expression types. This is an optimization > to avoid generating an extra bit inverse to check for equality. >
Patch is OK. Could you add an extra line in the sequence comment to say that it's because there's no comparison operator predicates and that we are instead using bitwise operations. Thanks, Tamar > gcc/ > > * config/aarch64/aarch64.cc (aarch64_instruction_selection): Flip > svbool_t == to != to avoid extra bit-inverse. > > gcc/testsuite/ > > * g++.target/aarch64/sve/acle/general-c++/svbool_ternary.C: New > test. > > Co-authored-by: Tamar Christina <[email protected]> > --- > gcc/config/aarch64/aarch64.cc | 63 +++++++++++++++++++ > .../sve/acle/general-c++/svbool_ternary.C | 13 ++++ > 2 files changed, 76 insertions(+) > create mode 100644 gcc/testsuite/g++.target/aarch64/sve/acle/general- > c++/svbool_ternary.C > > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > index 89097e23772..edfb03b1032 100644 > --- a/gcc/config/aarch64/aarch64.cc > +++ b/gcc/config/aarch64/aarch64.cc > @@ -2171,6 +2171,66 @@ aarch64_preferred_else_value (unsigned, tree, > unsigned int nops, tree *ops) > return nops == 3 ? ops[2] : ops[0]; > } > > +/* Implement TARGET_INSTRUCTION_SELECTION. The target hook is used to > + change generic sequences to a form AArch64 has an easier time expanding > + instructions for. It's not supposed to be used for generic rewriting that > + all targets would benefit from. */ > + > +static bool > +aarch64_instruction_selection (function * /* fun */, gimple_stmt_iterator > *gsi) > +{ > + auto stmt = gsi_stmt (*gsi); > + gassign *assign = dyn_cast<gassign *> (stmt); > + > + if (!assign) > + return false; > + > + /* Convert > + p == q ? s1 : s2; > + to > + p != q ? s2 : s1; > + where p and q are svbool_t expr. This avoids an extra inversion. */ > + if (gimple_assign_rhs_code (assign) != VEC_COND_EXPR) > + return false; > + > + tree lhs = gimple_assign_lhs (assign); > + tree rhs1 = gimple_assign_rhs1 (assign); > + tree rhs2 = gimple_assign_rhs2 (assign); > + tree rhs3 = gimple_assign_rhs3 (assign); > + > + if (TREE_CODE (rhs1) != SSA_NAME || !VECTOR_BOOLEAN_TYPE_P > (TREE_TYPE (rhs1))) > + return false; > + > + gassign *da = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (rhs1)); > + > + if (!da) > + return false; > + > + if (gimple_assign_rhs_code (da) != EQ_EXPR) > + return false; > + > + tree eqa = gimple_assign_rhs1 (da); > + tree eqb = gimple_assign_rhs2 (da); > + > + if (!VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqa)) > + || !VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (eqb))) > + return false; > + > + tree ne_expr_var = create_tmp_var (TREE_TYPE (rhs1)); > + gimple *ne_stmt = gimple_build_assign (ne_expr_var, NE_EXPR, eqa, eqb); > + gsi_safe_insert_before (gsi, ne_stmt); > + > + gimple *g = gimple_build_call_internal (IFN_VCOND_MASK, 3, > + ne_expr_var, rhs3, rhs2); > + if (!g) > + return false; > + > + gimple_set_lhs (g, lhs); > + gsi_replace (gsi, g, false); > + > + return true; > +} > + > /* Implement TARGET_HARD_REGNO_NREGS. */ > > static unsigned int > @@ -32882,6 +32942,9 @@ aarch64_libgcc_floating_mode_supported_p > #define TARGET_PREFERRED_ELSE_VALUE \ > aarch64_preferred_else_value > > +#undef TARGET_INSTRUCTION_SELECTION > +#define TARGET_INSTRUCTION_SELECTION aarch64_instruction_selection > + > #undef TARGET_INIT_LIBFUNCS > #define TARGET_INIT_LIBFUNCS aarch64_init_libfuncs > > diff --git a/gcc/testsuite/g++.target/aarch64/sve/acle/general- > c++/svbool_ternary.C b/gcc/testsuite/g++.target/aarch64/sve/acle/general- > c++/svbool_ternary.C > new file mode 100644 > index 00000000000..38de1880d1c > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/sve/acle/general- > c++/svbool_ternary.C > @@ -0,0 +1,13 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > + > +#include <arm_sve.h> > + > +svbool_t g (svbool_t p, svbool_t q, svbool_t a, svbool_t b, > + svbool_t c, svbool_t d) > +{ > + return (p == q) ? p : (a == b ? c : d); > +} > + > +/* { dg-final { scan-tree-dump-not {VEC_COND_EXPR} "optimized" } } */ > +/* { dg-final { scan-assembler-times {\teor\tp[0-9]+\.b} 2 } } */ > -- > 2.34.1
