https://gcc.gnu.org/g:b13ba91282e7f04a7eb350e0a1a1bdc6ba8a837d

commit r17-4227-gb13ba91282e7f04a7eb350e0a1a1bdc6ba8a837d
Author: Wilco Dijkstra <[email protected]>
Date:   Thu Jun 11 14:14:54 2026 +0000

    AArch64: Add tune for zeroing SVE move
    
    Add a new tune to select whether to prefer zeroing SVE move immediate or
    use the merging variant after zeroing the destination.  Since the expander
    is bypassed in multiple places, split after reload to zero the destination.
    Enable it on cores where the latter was measured to be slightly faster.
    
    With -mcpu=neoverse-v2 we now emit this for the testcase:
    
            movi    d0, #0
            mov     z0.s, p0/m, #1
    
    instead of:
    
            mov     z0.s, p0/z, #1
    
    This matches the floating point case (where there is no zeroing variant):
    
            movi    d0, #0
            fmov    z0.s, p0/m, #1.0
    
    gcc:
            * config/aarch64/aarch64.h (TARGET_SVE_PREFER_ZEROING_MOVIMM): New
            define.
            * config/aarch64/aarch64-sve.md (*vcond_mask_<mode><vpred>): Add a
            split condition for zero predicate.
            * config/aarch64/aarch64-tuning-flags.def: Add AVOID_MOVIMM_Z tune.
            * config/aarch64/tuning_models/neoversev1.h (tune_flags): Update.
            * config/aarch64/tuning_models/neoversev2.h (tune_flags): Update.
    
    gcc/testsuite:
            * gcc.target/aarch64/sve/zeroing_mov_z.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64-sve.md                  |  9 +++++++-
 gcc/config/aarch64/aarch64-tuning-flags.def        |  3 +++
 gcc/config/aarch64/aarch64.h                       |  4 ++++
 gcc/config/aarch64/tuning_models/neoversev1.h      |  3 ++-
 gcc/config/aarch64/tuning_models/neoversev2.h      |  1 +
 .../gcc.target/aarch64/sve/zeroing_mov_z.c         | 27 ++++++++++++++++++++++
 6 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-sve.md 
b/gcc/config/aarch64/aarch64-sve.md
index 1667145d3c71..8b15e25e8b50 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -8622,7 +8622,7 @@
 ;; This creates a false dependency on z0 which can result in stalls.
 ;; The zeroing will be done via a movi d0, 0 which is cheaper.
 ;;
-(define_insn "*vcond_mask_<mode><vpred>"
+(define_insn_and_rewrite "*vcond_mask_<mode><vpred>"
   [(set (match_operand:SVE_ALL 0 "register_operand")
        (unspec:SVE_ALL
          [(match_operand:<VPRED> 3 "aarch64_predicate_operand")
@@ -8640,6 +8640,13 @@
      [ ?&w      , vss , w  , Upa ; yes            ] movprfx\t%0, 
%2\;mov\t%0.<Vetype>, %3/m, #%I1
      [ ?&w      , Ufc , w  , Upa ; yes            ] movprfx\t%0, 
%2\;fmov\t%0.<Vetype>, %3/m, #%1
   }
+  "&& reload_completed
+   && aarch64_simd_or_scalar_imm_zero (operands[2], <MODE>mode)
+   && !TARGET_SVE_PREFER_ZEROING_MOVIMM"
+  {
+    emit_move_insn (operands[0], operands[2]);
+    operands[2] = copy_rtx (operands[0]);
+  }
 )
 
 ;; Optimize selects between a duplicated scalar variable and another vector.
diff --git a/gcc/config/aarch64/aarch64-tuning-flags.def 
b/gcc/config/aarch64/aarch64-tuning-flags.def
index 32bc1c4f3eec..64a773be34c0 100644
--- a/gcc/config/aarch64/aarch64-tuning-flags.def
+++ b/gcc/config/aarch64/aarch64-tuning-flags.def
@@ -81,4 +81,7 @@ AARCH64_EXTRA_TUNING_OPTION ("dispatch_sched", DISPATCH_SCHED)
    32 bits are unused.  */
 AARCH64_EXTRA_TUNING_OPTION ("narrow_gp_writes", NARROW_GP_WRITES)
 
+/* Enable when the target prefers SVE merging movimm over zeroing.  */
+AARCH64_EXTRA_TUNING_OPTION ("avoid_zeroing_movimm", AVOID_MOVIMM_Z)
+
 #undef AARCH64_EXTRA_TUNING_OPTION
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 6dec56df5cc1..39f51d4e92d7 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -522,6 +522,10 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE ATTRIBUTE_UNUSED
                                 && (aarch64_tune_params.extra_tuning_flags \
                                     & AARCH64_EXTRA_TUNE_AVOID_PRED_RMW))
 
+/* Set if we prefer SVE merging predicated mov immediate over zeroing.  */
+#define TARGET_SVE_PREFER_ZEROING_MOVIMM \
+  !(aarch64_tune_params.extra_tuning_flags & AARCH64_EXTRA_TUNE_AVOID_MOVIMM_Z)
+
 /* fp8 instructions are enabled through +fp8.  */
 #define TARGET_FP8 AARCH64_HAVE_ISA (FP8)
 
diff --git a/gcc/config/aarch64/tuning_models/neoversev1.h 
b/gcc/config/aarch64/tuning_models/neoversev1.h
index 253f11e87a68..004676a8dbac 100644
--- a/gcc/config/aarch64/tuning_models/neoversev1.h
+++ b/gcc/config/aarch64/tuning_models/neoversev1.h
@@ -229,7 +229,8 @@ static const struct tune_params neoversev1_tunings =
   (AARCH64_EXTRA_TUNE_BASE
    | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
    | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT
-   | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW),       /* tune_flags.  */
+   | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW
+   | AARCH64_EXTRA_TUNE_AVOID_MOVIMM_Z),       /* tune_flags.  */
   &generic_armv9a_prefetch_tune,
   AARCH64_LDP_STP_POLICY_ALWAYS,   /* ldp_policy_model.  */
   AARCH64_LDP_STP_POLICY_ALWAYS,   /* stp_policy_model.  */
diff --git a/gcc/config/aarch64/tuning_models/neoversev2.h 
b/gcc/config/aarch64/tuning_models/neoversev2.h
index 6df0cc444b80..734089772517 100644
--- a/gcc/config/aarch64/tuning_models/neoversev2.h
+++ b/gcc/config/aarch64/tuning_models/neoversev2.h
@@ -359,6 +359,7 @@ static const struct tune_params neoversev2_tunings =
    | AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS
    | AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT
    | AARCH64_EXTRA_TUNE_AVOID_PRED_RMW
+   | AARCH64_EXTRA_TUNE_AVOID_MOVIMM_Z
    | AARCH64_EXTRA_TUNE_AVOID_LDAPUR
    | AARCH64_EXTRA_TUNE_DISPATCH_SCHED),       /* tune_flags.  */
   &generic_armv9a_prefetch_tune,
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/zeroing_mov_z.c 
b/gcc/testsuite/gcc.target/aarch64/sve/zeroing_mov_z.c
new file mode 100644
index 000000000000..c257e8e7b720
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/zeroing_mov_z.c
@@ -0,0 +1,27 @@
+/* { dg-options "-O2 -mcpu=neoverse-v2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+/*
+** foo:
+**     movi    d0, #0
+**     mov     z0.s, p0/m, #1
+**     ret
+*/
+svint32_t foo (svbool_t pg)
+{
+  return svsel (pg, svdup_s32 (1), svdup_s32 (0));
+}
+
+/*
+** foo2:
+**     movi    d0, #0
+**     fmov    z0.s, p0/m, #1.0
+**     ret
+*/
+svfloat32_t foo2 (svbool_t pg)
+{
+  return svsel (pg, svdup_f32 (1.0f), svdup_f32 (0.0f));
+}
+

Reply via email to