https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128638
Bug ID: 128638
Summary: [16/17 Regression] wrong code at -O3: PRE moves a load
past a long long store by TBAA; the executed read is a
memcpy since r12-3918
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: alias, 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);
void *memcpy(void *, const void *, unsigned long);
int x = 1;
unsigned h(char *p, char *q) {
if (x)
*(float *)p = 2;
else
*(int *)p = 5;
*(long long *)q = 1;
unsigned t;
if (x)
memcpy(&t, p, 4);
else
t = *(int *)p;
return t;
}
unsigned (*fp)(char *, char *) = h;
int main(void) {
char *b = malloc(8);
printf("%x\n", fp(b, b));
}
$ gcc -O0 t.c && ./a.out
1
$ gcc -O3 t.c && ./a.out
40000000
Expected: 1. p == q. The long long 1 store at q overwrites the float 2.0f at p,
and the memcpy (alias set 0) must see it: t = 1. -O3 (and -O2
-ftree-partial-pre) gives 0x40000000, the bits of 2.0f. 13.4-15.2 do not show
it (hidden).
Suspected cause: PRE ANTIC: the load expression is hoisted past the store by
the TBAA of an int representative, but the read that runs is the memcpy (first
bad 5b8b1522e04, 2021, PR100112).
Avoided by: -fno-tree-pre, -fno-strict-aliasing.
Known to fail: 12.5.0, 16.2.0, 17.0.
Known to work: 8.5.0, 10.5.0, 11.4.0, 13.4.0, 14.3.0, 15.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