https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128461
Bug ID: 128461
Summary: wrong code at -O1: LIM store motion loses reverse
storage order since r9-4993
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jeffchen006 at gmail dot com
Target Milestone: ---
Target: x86_64-pc-linux-gnu
int printf(const char *, ...);
#pragma scalar_storage_order big-endian
struct S {
short a;
};
#pragma scalar_storage_order default
struct S g[2];
int n = 1;
int main(void)
{
int x = 0;
g[1].a = 2;
for (int i = 0; i < n; i++) {
x = g[1].a;
(&g[0])[1].a = 0;
}
printf("%d\n", x);
return 0;
}
$ gcc -O0 t.c && ./a.out
2
$ gcc -O1 t.c && ./a.out
512
-O1, -O2, -O3 all fail.
Expected: 2. g[1].a holds 2, and with big-endian storage order it must read
back as 2. At -O1 it reads as 512 (0x0200), so the bytes are read in native
order.
-fno-tree-loop-im avoids it. LIM moves the load and the store out of the loop
and does not preserve REF_REVERSE_STORAGE_ORDER. The program takes the address
of the struct, not of the reversed scalar.
Avoided by: -fno-tree-loop-im.
Bisected to r9-4993-g1c852d1d709.
Correct on 8.5.0.
Wrong on 10.5.0, 12.5.0, 13.4.0, 14.3.0, 15.2.0, 16.2.0, trunk.
-O0 -fsanitize=undefined,address is clean.
gcc version 17.0.0 20261029 (experimental), r17-5747-g85867b0c935,
x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release