> -----Original Message-----
> From: Tejas Belagod <[email protected]>
> Sent: 10 December 2025 11:51
> To: [email protected]
> Cc: Tejas Belagod <[email protected]>; Tamar Christina
> <[email protected]>; [email protected]
> Subject: [PATCH v4] 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.
>
> 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]>
Patch is OK.
Thanks,
Tamar
> ---
> gcc/config/aarch64/aarch64.cc | 65 +++++++++++++++++++
> .../sve/acle/general-c++/svbool_ternary.C | 13 ++++
> 2 files changed, 78 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 0ef22e8e52c..c694f948345 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -2180,6 +2180,68 @@ 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. Due to the absence of predicate
> + comparison instructions, we use bitwise xor for checking inequality.
> + Transforming == to != avoids an extra bitwise inversion to the xor. */
> + 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
> @@ -33109,6 +33171,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