https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118924
Bug ID: 118924 Summary: Wrong code leading to uninitialized accesses on aarch64-linux-gnu Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: acoplan at gcc dot gnu.org Target Milestone: --- The following testcase is miscompiled on the trunk with -O2 and above, on aarch64-linux-gnu: $ cat small.cc template <int Size> struct Vector { int m_data[Size]; Vector(int, int, int) {} }; enum class E { POINTS, LINES, TRIANGLES }; __attribute__((noipa)) void getName(E type) { static E check = E::POINTS; if (type == check) check = (E)((int)check + 1); else __builtin_abort (); } int main() { int arr[]{0, 1, 2}; for (auto dim : arr) { Vector<3> localInvs(1, 1, 1); localInvs.m_data[dim] = 8; } E types[] = {E::POINTS, E::LINES, E::TRIANGLES}; for (auto primType : types) getName(primType); } $ g++ small.cc $ ./a.out $ g++ -O small.cc $ ./a.out $ g++ -O2 small.cc $ ./a.out Aborted at -O1 we have the following in the optimized gimple for main: <bb 2> [local count: 268435458]: types[0] = 0; types[1] = 1; types[2] = 2; ivtmp.19_24 = (unsigned long) &types; _16 = ivtmp.19_24 + 12; <bb 3> [local count: 805306368]: # ivtmp.19_15 = PHI <ivtmp.19_17(3), ivtmp.19_24(2)> _23 = (void *) ivtmp.19_15; primType_8 = MEM[(E *)_23]; getName (primType_8); but at -O2 we have: <bb 2> [local count: 268435456]: ivtmp.21_15 = (unsigned long) &types; _10 = ivtmp.21_15 + 12; <bb 3> [local count: 805306368]: # ivtmp.21_12 = PHI <ivtmp.21_5(3), ivtmp.21_15(2)> _13 = (void *) ivtmp.21_12; primType_7 = MEM[(E *)_13]; getName (primType_7); i.e. at -O2 the initialization of the types array gets (incorrectly) optimized out. This can be verified by running valgrind on the binary compiled at -O2, which prints the following: ==1918879== Conditional jump or move depends on uninitialised value(s) ==1918879== at 0x4006AC: getName(E) (in /path/to/a.out) ==1918879== by 0x40055B: main (in /path/to/a.out) The problem seems to go at least as far back as GCC 11, but may be older.