https://gcc.gnu.org/g:035c1a3d24b4df437a631ae5770988088687debb

commit r16-9200-g035c1a3d24b4df437a631ae5770988088687debb
Author: Zhongjie Guo <[email protected]>
Date:   Wed Jun 17 03:29:15 2026 +0000

    i386: Adjust c86-4g-m7 512-bit memory costs
    
    c86-4g-m7 is a split-regs AVX512 target.  A 512-bit memory
    operation is implemented as two 256-bit halves, so the vectorizer cost
    model should not make 512-bit loads and stores almost as cheap as
    256-bit ones.
    
    The old c86_4g_m7_cost values made 512-bit loads/stores cost 12/12,
    close to or equal to the 256-bit 10/12 costs.  This can make 64-byte
    vectorization win in the loop body cost comparison even when 32-byte
    vectors avoid extra reduction epilogue work.
    
    Set the 512-bit load/store and unaligned load/store costs to twice the
    256-bit costs.  This removes the artificial 64-byte body-cost advantage;
    for dot-product style reduction loops, the reduction epilogue cost can
    then make 32-byte vectorization preferable.
    
    Compared with gcc-trunk without this tuning, local SPEC2006/SPEC2017
    testing shows improvements in several vector-width sensitive workloads.
    SPEC2006 1-copy fp_speed improved by 2.32%, including 436.cactusADM
    +12.39%, 433.milc +7.33%, and 459.GemsFDTD +4.76%.  SPEC2017 32-copy
    fprate improved by 0.40%, with 526.blender_r improving by 2.80%.
    
    gcc/ChangeLog:
    
            * config/i386/x86-tune-costs.h (c86_4g_m7_cost): Increase
            512-bit load/store and unaligned load/store costs.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/i386/c86-4g-m7-vect-load-cost-reduc.c: New test.
    
    Signed-off-by: Zhongjie Guo <[email protected]>
    (cherry picked from commit 57269888666b03dab3cec6cf9dd0aba669f2d267)

Diff:
---
 gcc/config/i386/x86-tune-costs.h                    | 12 ++++++------
 .../i386/c86-4g-m7-vect-load-cost-reduc.c           | 21 +++++++++++++++++++++
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h
index 7819fdf7c021..d2566bdbdcb7 100644
--- a/gcc/config/i386/x86-tune-costs.h
+++ b/gcc/config/i386/x86-tune-costs.h
@@ -4612,9 +4612,9 @@ struct processor_costs c86_4g_m7_cost = {
                                           in SImode and DImode.  */
   2, 2, 3,                             /* cost of moving XMM,YMM,ZMM
                                           register.  */
-  {6, 6, 10, 10, 12},                  /* cost of loading SSE registers
+  {6, 6, 10, 10, 20},                  /* cost of loading SSE registers
                                           in 32,64,128,256 and 512-bit.  */
-  {8, 8, 8, 12, 12},                   /* cost of storing SSE registers
+  {8, 8, 8, 12, 24},                   /* cost of storing SSE registers
                                           in 32,64,128,256 and 512-bit.  */
   6, 8,                                        /* SSE->integer and integer->SSE
                                           moves.  */
@@ -4654,12 +4654,12 @@ struct processor_costs c86_4g_m7_cost = {
                                           Relative to reg-reg move (2).  */
   {8, 8, 8},                           /* cost of storing integer
                                           registers.  */
-  {6, 6, 10, 10, 12},                  /* cost of loading SSE registers
+  {6, 6, 10, 10, 20},                  /* cost of loading SSE registers
                                           in 32bit, 64bit, 128bit, 256bit and 
512bit */
-  {8, 8, 8, 12, 12},                   /* cost of storing SSE register
+  {8, 8, 8, 12, 24},                   /* cost of storing SSE register
                                           in 32bit, 64bit, 128bit, 256bit and 
512bit */
-  {6, 6, 10, 10, 12},                  /* cost of unaligned loads.  */
-  {8, 8, 8, 12, 12},                   /* cost of unaligned stores.  */
+  {6, 6, 10, 10, 20},                  /* cost of unaligned loads.  */
+  {8, 8, 8, 12, 24},                   /* cost of unaligned stores.  */
   2, 2, 3,                             /* cost of moving XMM,YMM,ZMM
                                           register.  */
   6,                                   /* cost of moving SSE register to 
integer.  */
diff --git a/gcc/testsuite/gcc.target/i386/c86-4g-m7-vect-load-cost-reduc.c 
b/gcc/testsuite/gcc.target/i386/c86-4g-m7-vect-load-cost-reduc.c
new file mode 100644
index 000000000000..2be556cefb5b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/c86-4g-m7-vect-load-cost-reduc.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=c86-4g-m7 -mprefer-vector-width=512 -ffast-math 
-fdump-tree-vect-details" } */
+
+#define N 1024
+
+void foo (double *__restrict a, double *__restrict b, double *out)
+{
+  double sum = 1.0;
+
+  for (int i = 0; i < N; ++i)
+    sum += a[i] * b[i];
+
+  out[0] = sum;
+}
+
+/* On c86-4g-m7, 512-bit memory costs should model two 256-bit operations on
+   split-regs targets.  This loop exercises the load side of that model: once
+   the normalized body cost no longer favors 64-byte vectors, the reduction
+   epilogue cost makes 32-byte vectorization preferable.  */
+/* { dg-final { scan-tree-dump-times "optimized: loop vectorized using 32 byte 
vectors" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-not "optimized: loop vectorized using 64 byte 
vectors" "vect" } } */

Reply via email to