On Tue, Jun 16, 2026 at 11:10 AM Kewen Lin <[email protected]> wrote: > > Hi, > > This is authored-by: Zhongjie Guo <[email protected]>. > > 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%. > > Bootstrapped and regtested on a hygon c86-4g-m7 machine. > > Is it ok for trunk? Also ok to backport to gcc-16 after burn-in > time? (considering gcc-16 supports ix86-vect-compare-costs) > > BR, > Kewen > ----- > > 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.
OK everywhere. Thanks, Uros. > > Signed-off-by: Zhongjie Guo <[email protected]> > --- > 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(-) > create mode 100644 > gcc/testsuite/gcc.target/i386/c86-4g-m7-vect-load-cost-reduc.c > > diff --git a/gcc/config/i386/x86-tune-costs.h > b/gcc/config/i386/x86-tune-costs.h > index deb752889ac..8cbc2125973 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 00000000000..2be556cefb5 > --- /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" } } */ > -- > 2.34.1 >
