The current Neoverse V2 cost model underestimates the costs of SVE
structure loads and stores. This can cause the vectorizer to make a
suboptimal choice between AdvSIMD and SVE.
This patch brings the cost model in line with the latest Neoverse V2
Software Optimization Guide, which indicates that SVE structure loads
and stores are generally more expensive than the AdvSIMD versions.
Performance testing shows this change improves SPEC CPU 2026 735.ocio_r
by ~10.8% on Neoverse V2.
Bootstrapped and tested on aarch64-linux-gnu.
gcc/ChangeLog:
* config/aarch64/tuning_models/neoversev2.h: Update the costs
of SVE structure loads and stores.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/sve/cost_model_20.c: New test.
---
gcc/config/aarch64/tuning_models/neoversev2.h | 6 ++---
.../gcc.target/aarch64/sve/cost_model_20.c | 22 +++++++++++++++++++
2 files changed, 25 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/cost_model_20.c
diff --git a/gcc/config/aarch64/tuning_models/neoversev2.h
b/gcc/config/aarch64/tuning_models/neoversev2.h
index 15eff2807f7..6df0cc444b8 100644
--- a/gcc/config/aarch64/tuning_models/neoversev2.h
+++ b/gcc/config/aarch64/tuning_models/neoversev2.h
@@ -70,9 +70,9 @@ static const sve_vec_cost neoversev2_sve_vector_cost =
{
2, /* int_stmt_cost */
2, /* fp_stmt_cost */
- 2, /* ld2_st2_permute_cost */
- 3, /* ld3_st3_permute_cost */
- 3, /* ld4_st4_permute_cost */
+ 3, /* ld2_st2_permute_cost */
+ 4, /* ld3_st3_permute_cost */
+ 4, /* ld4_st4_permute_cost */
2, /* permute_cost */
/* Theoretically, a reduction involving 15 scalar ADDs could
complete in ~5 cycles and would have a cost of 15. [SU]ADDV
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cost_model_20.c
b/gcc/testsuite/gcc.target/aarch64/sve/cost_model_20.c
new file mode 100644
index 00000000000..77cb00cf1d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cost_model_20.c
@@ -0,0 +1,22 @@
+/* { dg-options "-O3 -mtune=neoverse-v2" } */
+
+void
+f (float *restrict in, float *restrict out, int num)
+{
+ for (int i = 0; i < num; ++i)
+ {
+ float r = in[4 * i];
+ float g = in[4 * i + 1];
+ float b = in[4 * i + 2];
+ float a = in[4 * i + 3];
+ out[4 * i] = r * 0.9f + g * 1.0f + b * 0.7f + a * 1.0f;
+ out[4 * i + 1] = r * 1.1f + g * 0.8f + b * 1.2f + a * 1.0f;
+ out[4 * i + 2] = r * 0.7f + g * 1.2f + b * 0.8f + a * 1.0f;
+ out[4 * i + 3] = r * 1.2f + g * 0.7f + b * 1.1f + a * 1.0f;
+ }
+}
+
+/* We should use AdvSIMD ld4/st4 rather than SVE for the vectorized main loop
+ on Neoverse-V2. */
+/* { dg-final { scan-assembler {\tld4\t} } } */
+/* { dg-final { scan-assembler {\tst4\t} } } */
--
2.43.0