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

Reply via email to