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
>

Reply via email to