Hi Tamar,

> So instead of
>
> mov     z0.s, p0/z, #5
> 
> we generate with the flag
> 
> movi    d0, #0
> fmov    z0.s, p0/m, #1.0

Correct - and that is exactly what we already do for FP immediates since there 
is
no zeroing variant.

> ? Weird but sure I believe you. But should aarch64_sel_dup<mode> also get the
> same treatment then? You previously changed this to drop the movprfx version
> so I'd expect the same behaviour?

It already does, I removed all the zeroing movprfx variants, so they already 
use movi.
This case is the last zeroing variant.

> Could you also please add a testcase for the tune.

Done.

Cheers,
Wilco


v2: Add testcase, improve description

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

Passes regress, OK for commit?

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 --git a/gcc/config/aarch64/aarch64-sve.md 
b/gcc/config/aarch64/aarch64-sve.md
index 
1667145d3c71c14b7d19e32d14f521c8f3c91ad7..8b15e25e8b50dd671174b8c971589e904f95607f
 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -8622,7 +8622,7 @@ (define_expand "@vcond_mask_<mode><vpred>"
 ;; 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 @@ (define_insn "*vcond_mask_<mode><vpred>"
      [ ?&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 
32bc1c4f3eecf04f35740bb573ea39c8449cf901..64a773be34c0c28e18a1c2b3b0a84ce369633010
 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 
fdedb04391127c5a1b821ed5d4b399c1c28d9f31..c7fa687514e48aad2897ddc85880a4685c3b7602
 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -519,6 +519,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 
253f11e87a68548a51201ee8e1318aaae606cab2..004676a8dbacf438beb5c5598a39f80988bb6a48
 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 
6df0cc444b804cf098e8f16d10d7afff6340dd9e..734089772517e69af448dd44acf5b20982b8cc3a
 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 
0000000000000000000000000000000000000000..c257e8e7b72014d672c92d94f27aeaa8ededd6f8
--- /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