[Bug target/126619] New: [17 Regression] Slowdown of s116 from TSVC on x86_64 since r17-2876-gf0bd50e8317926
"pheeck at gcc dot gnu.org via Gcc-bugs" <[email protected]> Mon, 03 Aug 2026 16:10:59 +0000
| Newsgroups | gmane.comp.gcc.bugs |
|---|---|
| Message-ID | <[email protected]/bugzilla/> |
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D126619
Bug ID: 126619
Summary: [17 Regression] Slowdown of s116 from TSVC on x86_64
since r17-2876-gf0bd50e8317926
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: pheeck at gcc dot gnu.org
CC: sayle at gcc dot gnu.org
Target Milestone: ---
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
I observe slowdowns of the s116 benchmark from the TSVC benchmark suite.
AMD zen2:
-O2 generic march
https://lnt.opensuse.org/db_default/v4/CPP/graph?plot.0=3D176.815.0
-Ofast -march=3Dnative
https://lnt.opensuse.org/db_default/v4/CPP/graph?plot.0=3D171.815.0
Intel Ice Lake (3rd generation Xeon):
-O2 generic march
https://lnt.opensuse.org/db_default/v4/CPP/graph?plot.0=3D466.815.0
-Ofast -march=3Dnative
https://lnt.opensuse.org/db_default/v4/CPP/graph?plot.0=3D463.815.0
AMD zen3:
-O2 generic march
https://lnt.opensuse.org/db_default/v4/CPP/graph?plot.0=3D286.815.0
-Ofast -march=3Dnative
https://lnt.opensuse.org/db_default/v4/CPP/graph?plot.0=3D283.815.0
AMD zen4:
-O2 generic march
https://lnt.opensuse.org/db_default/v4/CPP/graph?plot.0=3D556.815.0
AMD zen5:
-O2 generic march
https://lnt.opensuse.org/db_default/v4/CPP/graph?plot.0=3D994.815.0
-Ofast -march=3Dnative
https://lnt.opensuse.org/db_default/v4/CPP/graph?plot.0=3D987.815.0
I extracted the benchmark from the benchmark suite:
--- mytestcase.c ---
#include <time.h>=20=20=20=20
#include <stdio.h>=20=20=20=20
#include <stdlib.h>=20=20=20=20
#include <string.h>=20=20=20=20
#include <math.h>=20=20=20=20
#include <sys/time.h>=20=20=20=20
#define ARRAY_ALIGNMENT 64=20=20=20=20
#define LEN_1D 32000=20=20=20=20
#define iterations 100000=20=20=20=20
extern __attribute__((aligned(ARRAY_ALIGNMENT))) float a[LEN_1D];=20=20=20=
=20
int dummy(float[LEN_1D]);=20=20=20=20
void initialise_a();=20=20=20=20
__attribute__((aligned(ARRAY_ALIGNMENT))) float a[LEN_1D];=20=20=20=20
int main()=20=20=20=20
{=20=20=20=20
// linear dependence testing=20=20=20=20
initialise_a();=20=20=20=20
for (int nl =3D 0; nl < iterations*10; nl++) {=20=20=20=20
for (int i =3D 0; i < LEN_1D - 5; i +=3D 5) {=20=20=20=20
a[i] =3D a[i + 1] * a[i];=20=20=20=20
a[i + 1] =3D a[i + 2] * a[i + 1];=20=20=20=20
a[i + 2] =3D a[i + 3] * a[i + 2];=20=20=20=20
a[i + 3] =3D a[i + 4] * a[i + 3];=20=20=20=20
a[i + 4] =3D a[i + 5] * a[i + 4];=20=20=20=20
}=20=20=20=20
dummy(a);=20=20=20=20
}=20=20=20=20
return 0;=20=20=20=20
}
--- ---
--- mytestcase2.c ---
#include <stdio.h>=20=20=20
#include <stdlib.h>=20=20=20
#include <malloc.h>=20=20=20=20
#include <string.h>=20=20=20=20
#include <math.h>=20=20=20=20
#define ARRAY_ALIGNMENT 64
#define LEN_1D 32000=20=20=20=20=20=20=20=20=20=20
extern __attribute__((aligned(ARRAY_ALIGNMENT))) float a[LEN_1D];
void initialise_a()=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20
{=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20
for (int i =3D 0; i < LEN_1D; i++) {
a[i] =3D 1.;
}=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20
}=20=20=20=20
int dummy(float a[LEN_1D])
{=20=20=20=20
return 0;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20
}
--- ---
If I build GCC from r17-2876, compile the testcase and run it, I get longer
runtime than with r17-2875 GCC.
gcc-r17-2876 -O2 mytestcase{,2}.c -o tsvc
time ./tsvc
real 0m6.224s
user 0m6.223s
sys 0m0.000s
gcc-r17-2875 -O2 mytestcase{,2}.c -o tsvc
time ./tsvc
real 0m4.665s
user 0m4.665s
sys 0m0.000s
(I did this experiment on an AMD Zen5 machine)
Thus, I believe this slowdown is caused by r17-2876-gf0bd50e8317926
commit f0bd50e831792692ffcedf288b312167a9339260
Author: Roger Sayle <[email protected]>
AuthorDate: Sat Aug 1 17:51:02 2026 +0100
Commit: Roger Sayle <[email protected]>
CommitDate: Sat Aug 1 17:53:52 2026 +0100
x86 SSE: Improved vector initialization/construction.
Here's a diff of the disassembly of the main function. The - lines are
r17-2875, the + lines are r17-2876.
diff -u --color=3Dauto tsvc-before-suspect.s tsvc-suspect.s
--- tsvc-before-suspect.s 2026-08-03 17:50:27.178228585 +0200
+++ tsvc-suspect.s 2026-08-03 17:50:26.253068980 +0200
@@ -1,5 +1,5 @@
-tsvc-before-suspect: file format elf64-x86-64
+tsvc-suspect: file format elf64-x86-64
Disassembly of section .init:
@@ -16,42 +16,38 @@
Disassembly of section .text:
-0000000000401040 <main>:
+0000000000401020 <main>:
53 push %rbx
bb 40 42 0f 00 mov $0xf4240,%ebx
-e8 95 01 00 00 call 4011e0 <initialise_a>
-f3 0f 10 05 2d 30 00 movss 0x302d(%rip),%xmm0 # 404080 <a>
+e8 75 01 00 00 call 4011a0 <initialise_a>
+f3 0f 10 05 4d 30 00 movss 0x304d(%rip),%xmm0 # 404080 <a>
00=20
b8 80 40 40 00 mov $0x404080,%eax
-0f 1f 80 00 00 00 00 nopl 0x0(%rax)
-66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1)
-00 00 00 00=20
-66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1)
-00 00 00 00=20
-66 66 2e 0f 1f 84 00 data16 cs nopw 0x0(%rax,%rax,1)
-00 00 00 00=20
-f3 0f 10 48 10 movss 0x10(%rax),%xmm1
-f3 0f 10 58 0c movss 0xc(%rax),%xmm3
+0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
+00=20
+66 0f 7e c2 movd %xmm0,%edx
+0f 10 48 04 movups 0x4(%rax),%xmm1
+f3 0f 10 50 08 movss 0x8(%rax),%xmm2
+f3 0f 10 58 10 movss 0x10(%rax),%xmm3
+66 0f 6e c2 movd %edx,%xmm0
48 83 c0 14 add $0x14,%rax
-f3 0f 10 60 f4 movss -0xc(%rax),%xmm4
-0f 10 50 f0 movups -0x10(%rax),%xmm2
-0f 14 d9 unpcklps %xmm1,%xmm3
-0f 14 c4 unpcklps %xmm4,%xmm0
-0f c6 d2 90 shufps $0x90,%xmm2,%xmm2
-0f 16 c3 movlhps %xmm3,%xmm0
-0f 59 c2 mulps %xmm2,%xmm0
+0f 14 c2 unpcklps %xmm2,%xmm0
+f3 0f 10 50 f8 movss -0x8(%rax),%xmm2
+0f 14 d3 unpcklps %xmm3,%xmm2
+0f c6 c9 90 shufps $0x90,%xmm1,%xmm1
+0f 16 c2 movlhps %xmm2,%xmm0
+0f 59 c1 mulps %xmm1,%xmm0
+f3 0f 10 48 fc movss -0x4(%rax),%xmm1
0f 11 40 ec movups %xmm0,-0x14(%rax)
f3 0f 10 00 movss (%rax),%xmm0
f3 0f 59 c8 mulss %xmm0,%xmm1
f3 0f 11 48 fc movss %xmm1,-0x4(%rax)
48 3d 6c 34 42 00 cmp $0x42346c,%rax
-75 c0 jne 401080 <main+0x40>
+75 b3 jne 401040 <main+0x20>
bf 80 40 40 00 mov $0x404080,%edi
-e8 56 01 00 00 call 401220 <dummy>
+e8 49 01 00 00 call 4011e0 <dummy>
83 eb 01 sub $0x1,%ebx
-0f 85 78 ff ff ff jne 40104b <main+0xb>
+75 8f jne 40102b <main+0xb>
31 c0 xor %eax,%eax
5b pop %rbx
c3 ret
-66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
-00 00
Different vector instructions are used, but I didn't dive deep enough into =
this
to understand why the ones chosen by r17-2875 perform better. Roger, can y=
ou
make sense of this? Can something reasonable be done to make GCC emit the
faster instructions in this testcase?=