On Wed, 23 Sep 2026, Hongtao Liu wrote:

> On Wed Sep 23, 2026 at 2:11 AM PDT, Richard Biener wrote:
> > vec_to_scalar costs a lane extraction which might be lane zero
> > from a vector to a scalar.  The following makes us account for
> > the extra cost when the target is a GPR.
> >
> > I chose to not limit the testcase to any tuning/ISA, it shouldn't
> > be vectorized for any combination.
> >
> > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> >
> > OK?
> Ok.
> 
> BTW, I realized that could be the reason H.J posted
> https://gcc.gnu.org/pipermail/gcc-patches/2026-September/730504.html
> And this commit should address PR127268.

Ah, indeed.  I have added it as reference and also amended the
patch with two comments indicating that vec_to_scalar is always
a full splat.  So for example for V16QI with just SSE2 it can
be quite expensive with the usual QI->SI->V4SI[0] initialization
followed by multiplying with 0x01010101 and then splatting V4SI[0].
Luckily we do that only in the epilog for loop vectorization, but
for BB vectorization more precise costing might help.

I'll leave the patch for comments from HJ and will probably push
somewhen tomorrow.

Thanks,
Richard.


>From 77fe93d1a3ab33e4331036de86baa451ff4aaee4 Mon Sep 17 00:00:00 2001
From: Richard Biener <[email protected]>
Date: Wed, 23 Sep 2026 11:04:39 +0200
Subject: [PATCH] [x86] account for SSE to integer move cost for vec_to_scalar
To: [email protected]

vec_to_scalar costs a lane extraction which might be lane zero
from a vector to a scalar.  The following makes us account for
the extra cost when the target is a GPR.

I chose to not limit the testcase to any tuning/ISA, it shouldn't
be vectorized for any combination.

        PR target/127268
        * config/i386/i386.cc (ix86_default_vector_cost): For
        integer mode vec_to_scalar add sse_to_integer cost.

        * gcc.target/i386/vect-bb-reduc-1.c: New testcase.
---
 gcc/config/i386/i386.cc                         |  5 +++++
 gcc/testsuite/gcc.target/i386/vect-bb-reduc-1.c | 13 +++++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/vect-bb-reduc-1.c

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 705ebb6c014..b09a5077820 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -26045,7 +26045,12 @@ ix86_default_vector_cost (enum vect_cost_for_stmt 
type_of_cost,
         return COSTS_N_INSNS (ix86_cost->sse_store[index]) / 2;
 
       case vec_to_scalar:
+       /* This is a lane extraction, possibly from lane zero.  */
+       return (ix86_vec_cost (mode, ix86_cost->sse_op)
+               + (fp ? 0 : COSTS_N_INSNS (ix86_cost->sse_to_integer) / 2));
+
       case scalar_to_vec:
+       /* This is always a full splat from scalar, not a lane insertion.  */
         return ix86_vec_cost (mode, ix86_cost->sse_op);
 
       /* We should have separate costs for unaligned loads and gather/scatter.
diff --git a/gcc/testsuite/gcc.target/i386/vect-bb-reduc-1.c 
b/gcc/testsuite/gcc.target/i386/vect-bb-reduc-1.c
new file mode 100644
index 00000000000..c8efbb8c24f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-bb-reduc-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern unsigned char *var1;
+extern unsigned short var2;
+void
+func (void)
+{
+  var2 = var1[1] + var1[0];
+}
+
+/* We do not want to vectorize the reduction.  */
+/* { dg-final { scan-assembler-not "xmm" } } */
-- 
2.51.0

Reply via email to