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" } } */
