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.