> -----Original Message-----
> From: Tejas Belagod <[email protected]>
> Sent: 13 November 2025 12:49
> To: [email protected]
> Cc: Tejas Belagod <[email protected]>; Tamar Christina
> <[email protected]>; Tamar Christina <[email protected]>
> Subject: [PATCH] AArch64: Flip svbool_t equal conditionals in ternary
> operators.
> 
> This is a follow-up to Tamar's target hook patch:
>  https://gcc.gnu.org/pipermail/gcc-patches/2025-November/700417.html
> 
> 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_preferred_instruction_selection):
>       Flip svbool_t == to != to avoid extra bit-inverse.
> 

Indentation seems wrong here.

> gcc/testsuite/
> 
>       * g++.target/aarch64/sve/acle/general-c++/svbool_ternary.C: New
> test.
> 
> Co-authored-by: Tamar Christina <[email protected]>

Extra r in my name :)

Patch is OK once the middle-end changes go it.

FWIW early next stage-1 I plan to submit an aarch64-match.pd equivalent
that can be used here which would simplify this code.

Thanks for working on it.

Regards,
Tamar

> ---
>  gcc/config/aarch64/aarch64.cc                 | 62 +++++++++++++++++++
>  .../sve/acle/general-c++/svbool_ternary.C     | 12 ++++
>  2 files changed, 74 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 60608a19078..28ba2284209 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -2171,6 +2171,65 @@ aarch64_preferred_else_value (unsigned, tree,
> unsigned int nops, tree *ops)
>    return nops == 3 ? ops[2] : ops[0];
>  }
> 
> +/* Implement TARGET_PREFERRED_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_preferred_instruction_selection (function * /* fun */,
> +                                      gimple_stmt_iterator *gsi)
> +{
> +  auto stmt = gsi_stmt (*gsi);
> +  gassign *assign = dyn_cast<gassign *> (stmt);
> +
> +  if (!assign)
> +    return false;
> +
> +  tree_code code = gimple_assign_rhs_code (assign);
> +
> +  if (code != 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;
> +
> +  auto ds = SSA_NAME_DEF_STMT (rhs1);
> +  gassign *da = dyn_cast<gassign *> (ds);
> +
> +  if (!da)
> +    return false;
> +
> +  code = gimple_assign_rhs_code (da);
> +
> +  if (code != 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));
> +  tree ne_expr = build2 (NE_EXPR, TREE_TYPE (rhs1), eqa, eqb);
> +  gimple *ne_stmt = gimple_build_assign (ne_expr_var, ne_expr);
> +  gsi_safe_insert_before (gsi, ne_stmt);
> +
> +  tree new_vce = build3 (VEC_COND_EXPR, TREE_TYPE (lhs),
> +                      ne_expr_var, rhs3, rhs2);
> +  gimple *vce_stmt = gimple_build_assign (lhs, new_vce);
> +  gsi_replace (gsi, vce_stmt, false);
> +
> +  return true;
> +}
> +
>  /* Implement TARGET_HARD_REGNO_NREGS.  */
> 
>  static unsigned int
> @@ -32872,6 +32931,9 @@ aarch64_libgcc_floating_mode_supported_p
>  #undef TARGET_PREFERRED_ELSE_VALUE
>  #define TARGET_PREFERRED_ELSE_VALUE \
>    aarch64_preferred_else_value
> +#undef TARGET_PREFERRED_INSTRUCTION_SELECTION
> +#define TARGET_PREFERRED_INSTRUCTION_SELECTION \
> +  aarch64_preferred_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..91cb3244aaa
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/aarch64/sve/acle/general-
> c++/svbool_ternary.C
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +#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-assembler-times {\teor\tp[0-9]+\.b} 2 } } */
> --
> 2.34.1

Reply via email to