https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104067
Bug ID: 104067 Summary: wrong code compiling QEMU Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: blocker Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: bonzini at gnu dot org Target Milestone: --- Target: x86_64-pc-linux-gnu Compiling QEMU's tests/unit/rcutorture.c file with GCC 12 causes an incorrect optimization Here is a reduced testcase: extern void abort(); struct rcu_stress { int x; }; struct rcu_stress rcu_stress_array[10] = { { 0 } }; struct rcu_stress *rcu_stress_current; int main(int argc, char *argv[]) { int i, rcu_stress_idx = 0; struct rcu_stress *cp = rcu_stress_array; for (i = 100; --i > 0; ) { struct rcu_stress *p; rcu_stress_idx++; if (rcu_stress_idx >= 10) { rcu_stress_idx = 0; } p = &rcu_stress_array[rcu_stress_idx]; if (p == cp) abort(); __atomic_thread_fence(5); cp = p; } } $ /opt/gcc-latest/bin/gcc -m64 -mcx16 -std=gnu11 -O2 -fno-strict-aliasing -fno-common -fwrapv gccbug.c -o gccbug -pthread && ./gccbug Aborted (core dumped) $ gcc -m64 -mcx16 -std=gnu11 -O2 -fno-strict-aliasing -fno-common -fwrapv gccbug.c -o gccbug -pthread && ./gccbug The issue seems to be that when "p" is assigned &rcu_stress_array[10], gcc decides it's undefined behavior and triggers the abort. The first problematic dump is .194t.threadfull2: <bb 5> [count: 0]: abort (); ... <bb 7> [local count: 1052374367]: # rcu_stress_idx_21 = PHI <rcu_stress_idx_2(6)> # cp_7 = PHI <prephitmp_16(6)> # ivtmp_12 = PHI <ivtmp_3(6)> rcu_stress_idx_20 = rcu_stress_idx_21 + 1; if (rcu_stress_idx_20 == 10) goto <bb 8>; [34.00%] else goto <bb 3>; [66.00%] <bb 8> [local count: 357807289]: # rcu_stress_idx_5 = PHI <0(7)> # prephitmp_9 = PHI <&rcu_stress_array(7)> goto <bb 5>; [100.00%]