https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128647
Bug ID: 128647
Summary: [17 Regression] wrong code at -O3: PRE gives a struct
load the value of an older store past a may-alias
struct store
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: alias, needs-bisection, wrong-code
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jeffchen006 at gmail dot com
Target Milestone: ---
int printf(const char *, ...);
void *malloc(unsigned long);
struct L1 { long v; };
struct L1b { long v; };
static long f2(char *b, int o, int m) {
*(double *)(b + o) = 1;
if (m == 0)
return *(long *)b;
return 0;
}
static long f3(char *b, int o, int m, int k) {
long r = 0;
for (int i = 0; i < 2; i++) {
int md = (m + i) & 1, kk = (k + i) & 1;
if (md == 0) ((struct L1 *)(b + o))->v = 5;
else ((struct L1b *)(b + o))->v = 6;
if (kk == 0) r += ((struct L1 *)b)->v;
else r += ((struct L1b *)b)->v;
}
return r;
}
int main(int argc, char **argv) {
int ms[2] = {2, 2};
int z = argc - 1, ks[2] = {2 + z, 2 + z};
char *b = (char *)malloc(64);
long h = 0;
for (int it = 0; it < 2; it++) {
h += f2(b, z, ms[it] + z);
h += f3(b, z, ms[it] + z, ks[it]);
}
printf("%ld\n", h);
}
$ gcc -O0 t.c && ./a.out
22
$ gcc -O3 t.c && ./a.out
18
Expected: 22. Each f3 iteration stores L1 or L1b at b and reads back the same
type at b, so it reads 5 or 6 (m == k on every run). Sum: 22. 13.4-16.2 do not
show it (hidden).
Suspected cause: full PRE phi-translation: the L1/L1b load gets the value of
the older double store past a may-alias struct store.
Avoided by: -fno-tree-pre, -fno-strict-aliasing.
Known to fail: 7.5.0, 8.5.0, 10.5.0, 12.5.0, 17.0.
Known to work: 13.4.0, 14.3.0, 15.2.0, 16.2.0.
-O0 -fsanitize=undefined,address is clean.
gcc version 17.0.0 20261111 (experimental) (a2a11abfad3), x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release