https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128434
Bug ID: 128434
Summary: BB SLP builds address vectors at function entry that
are hoisted from rarely block inside of loop.
Product: gcc
Version: 16.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: hyeonseongyang09 at gmail dot com
Target Milestone: ---
When a block inside a loop writes several constants into an array, BB SLP
combines the writes into vector stores.
The vectors code always hoist into start of the SLP region. so this moves them
out of the loop to the function entry.
But this makes fill the constants on every call, even if the block
runs only once or never.
I attach some simplified code of this issue.
Expected: the addresses are loaded in the OP_INIT case, where they are
stored.
Actual: they are loaded at the start of run(), before the loop, on every
call.
Testcase:
enum { OP_INC, OP_DOUBLE, OP_DEC, OP_HALT, OP_INIT };
void f_inc(void);
void f_dec(void);
void f_double(void);
void f_square(void);
void f_neg(void);
void f_half(void);
void f_print(void);
void f_halt(void);
void (*callbacks[8])(void);
long run(int *pc, long acc)
{
for (;;) {
switch (*pc++) {
case OP_INC: acc += 1; break;
case OP_DOUBLE: acc *= 2; break;
case OP_DEC: acc -= 3; break;
case OP_HALT: return acc;
case OP_INIT:
callbacks[0] = f_inc;
callbacks[1] = f_dec;
callbacks[2] = f_double;
callbacks[3] = f_square;
callbacks[4] = f_neg;
callbacks[5] = f_half;
callbacks[6] = f_print;
callbacks[7] = f_halt;
break;
}
}
}
Start of run() before the loop:
run:
movq .LC0(%rip), %xmm3
movq %rsi, %rax
movq .LC2(%rip), %xmm2
movhps .LC1(%rip), %xmm3
movq .LC4(%rip), %xmm1
movhps .LC3(%rip), %xmm2
movq .LC6(%rip), %xmm0
movhps .LC5(%rip), %xmm1
movhps .LC7(%rip), %xmm0
.L2:
cmpl $4, (%rdi)
...
(.LC0 - .LC7 hold the addresses of f_inc ... f_halt.)
For comparison, this is code from Clang 22 -O2:
run:
movq %rsi, %rax
.L2:
jmpq *-8(%rdi)
Environment:
$ gcc -v
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap
--enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,m2,cobol,algol68,lto
--prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=https://bugzilla.redhat.com/ --enable-shared
--enable-threads=posix --enable-checking=release --with-system-zlib
--enable-__cxa_atexit --disable-libunwind-exceptions
--enable-gnu-unique-object --enable-linker-build-id
--with-gcc-major-version-only --enable-plugin --enable-initfini-array
--enable-libstdcxx-backtrace
--with-libstdcxx-zoneinfo=/usr/share/zoneinfo --with-isl=...
--enable-gnu-indirect-function --enable-multilib
--with-linker-hash-style=gnu
--enable-offload-targets=nvptx-none,amdgcn-amdhsa
--enable-offload-defaulted --without-cuda-driver --enable-cet
--with-tune=generic --with-tls=gnu2 --with-arch_32=i686
--build=x86_64-redhat-linux --with-build-config=bootstrap-lto
--enable-link-serialization=1 --disable-libssp
Thread model: posix
gcc version 16.2.1 20261029 (Red Hat 16.2.1-3) (GCC)
Command line:
$ gcc -O2 -S toy-interp.c -Wall -Wextra
No warnings.