https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66272
Mikhail Maltsev <miyuki at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Known to work| |4.8.4 Keywords| |wrong-code Last reconfirmed| |2015-05-24 CC| |miyuki at gcc dot gnu.org Ever confirmed|0 |1 Summary|wrong code at -O3 on |[4.9.2/5/6 Regression] |x86_64-linux-gnu |wrong code at -O3 on | |x86_64-linux-gnu Known to fail| |4.9.2, 5.1.0, 6.0 --- Comment #1 from Mikhail Maltsev <miyuki at gcc dot gnu.org> --- The testcase can be simplified a bit (I eliminated variable c and moved array a inside main, so it's now local). struct S { int f0; int f1; }; int b; int main () { struct S a[2] = { 0 }; struct S d = { 0, 1 }; for (b = 0; b < 2; b++) { a[b] = d; d = a[0]; } if (d.f1 != 1) __builtin_abort (); } Wrong transformation is made in predictive commoning pass (the program compiled with -O3 -fno-predictive-commoning does not abort). The store d.f1 = a[0].f1; is assumed to be independent of the previous store to a[b] (which is obviously wrong) and it is hoisted out of the loop. I think the reason is that find_data_references_in_stmt or some related function misenterprets MEM[(struct S[2] *)&a + 4B] as some object that does not alias with MEM[(struct S *)&a]'s SCEV. By the way, the expression itself looks strange: struct S * should be "a", not "&a". (Data Dep: #(Data Ref: # bb: 3 # stmt: MEM[(struct S *)_4 + 4B] = d$f1_7; # ref: MEM[(struct S *)_4 + 4B]; # base_object: MEM[(struct S *)&a]; # Access function 0: {4B, +, 8}_1 #) #(Data Ref: # bb: 3 # stmt: d$f1_16 = MEM[(struct S[2] *)&a + 4B]; # ref: MEM[(struct S[2] *)&a + 4B]; # base_object: MEM[(struct S[2] *)&a + 4B]; #) (no dependence) ) If I scalarize the assignment d = a[0] (I mean, in the source), the bug disappears.