Link to the Compiler Explorer: https://godbolt.org/z/3GE6fKvYr Reproducer: #include <stdio.h> char a = 0; long long b[8][10][18]; void e(int, long long[][10][18]) __attribute__((noipa)); void e(int f, long long g[][10][18]) { for (int d = 0; d < f; d += 3LL) for (int c = 0; c < ((f ? g[5][0][0] : 0) ^ g[5][0][0]) + 1; c++) a = 42; } int main() { for (size_t i = 0; i < 8; ++i) for (size_t k = 0; k < 10; ++k) for (size_t j = 0; j < 8; ++j) b[i][k][j] = -1311387439415292401LL; e(8, b); printf("%u\n", a); if (a != 42) __builtin_abort(); } Error: >$ g++ -O1 driver.cpp && ./a.out 42 >$ g++ -O2 driver.cpp && ./a.out 0 gcc version 12.0.0 20211123 (721d8b9e26bf8205c1f2125c2626919a408cdbe4) (GCC)
Confirmed reduced testcase: int t1 = -2; int e(int) __attribute__((noipa)); int e(int f) { int t = 0; for (int d = 0; d < f; d ++) { for (int c = 0; c < ((f ? t1 : 0) ^ t1) + 1; c++) t= 42; } return t; } int main() { unsigned a = e(1); printf("%u\n", a); if (a != 42) __builtin_abort (); } Note the t1 being negative is important. t1 being global is also important, if you do a load of t1 before either loop, you end up with working code. THis is another bswap issue ...
Before bswap, we have: iftmp.0_11 = t1; t1.1_1 = t1; _2 = t1.1_1 ^ iftmp.0_11; But after we get: load_dst_8 = MEM[(int *)&t1]; _2 = (int) load_dst_8; Which is wrong as _2 should have been 0.
Dup of bug 103376. *** This bug has been marked as a duplicate of bug 103376 ***