https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128646
Bug ID: 128646
Summary: wrong code at -O2: modref misses a pointer returned
through __builtin_bit_cast; stores lost
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: ipa
Assignee: unassigned at gcc dot gnu.org
Reporter: jeffchen006 at gmail dot com
Target Milestone: ---
#include <cstdio>
struct X { int *p; };
X foo(int *p, int n) {
for (int k = 0; k < n; k++)
if (p[k] == 7 * k + 3 || p[k] == 11 * k - 5 || p[k] == 13 * k + 1 || p[k]
== 17 * k + 9 || p[k] == 19 * k - 2 || p[k] == 23 * k + 4 || p[k] == 29 * k -
8)
p[k] = 0;
return __builtin_bit_cast(X, p);
}
int main() {
int a = 0, b = 0;
X xa = foo(&a, 1), xb = foo(&b, 1);
*xa.p = 1;
*xb.p = 2;
printf("%d %d\n", a, b);
}
$ g++ -O0 t.cpp && ./a.out
1 2
$ g++ -O2 t.cpp && ./a.out
1 0
Expected: 1 2. foo returns p through a struct made by __builtin_bit_cast, so
*xb.p = 2 writes b. -O3 prints "0 0". The loop only stops inlining. GCC's own
gcc.dg/sso-15.c (dg-do compile) aborts when run at -O1 since GCC 12.
Suspected cause: ipa-modref EAF analysis does not see "*lhs =
VIEW_CONVERT_EXPR<T>(name)" as a return/escape of name, so the parameter is
"not returned" and points-to misses the alias.
Avoided by: -fno-ipa-modref, -fno-tree-pta.
Known to fail: 12.5.0, 13.4.0, 14.3.0, 15.2.0, 16.2.0, 17.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