https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69547
Bug ID: 69547 Summary: no-op array initializer emits an empty loop Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- Given code like the following, even at -O2 GCC emits a loop iterating over all the uninitialized elements in the array. struct A { A () { } }; void foo (void*, int); void bar () { enum { N = 64 }; A a [N]; foo (&a, N); } For example, the powerpc64le object code looks like this but the same no-op loop can be found in x86_64 object code: 0000000000000000 <_Z3barv>: 0: 00 00 4c 3c addis r2,r12,0 4: 00 00 42 38 addi r2,r2,0 8: a6 02 08 7c mflr r0 c: 40 00 20 39 li r9,64 10: a6 03 29 7d mtctr r9 14: 10 00 01 f8 std r0,16(r1) 18: a1 ff 21 f8 stdu r1,-96(r1) 1c: 00 00 42 60 ori r2,r2,0 20: 00 00 00 42 bdnz 20 <_Z3barv+0x20> <<< no-op loop on ctr 24: 20 00 61 38 addi r3,r1,32 28: 40 00 80 38 li r4,64 2c: 01 00 00 48 bl 2c <_Z3barv+0x2c> 30: 00 00 00 60 nop 34: 60 00 21 38 addi r1,r1,96 38: 10 00 01 e8 ld r0,16(r1) 3c: a6 03 08 7c mtlr r0 40: 20 00 80 4e blr I expected the loop to be eliminated by the middle end but I can see it even in the last optimization pass: u.cpp.210t.optimized ;; Function void bar() (_Z3barv, funcdef_no=3, decl_uid=2141, cgraph_uid=3, symbol_order=3) Removing basic block 5 void bar() () { unsigned long ivtmp.12; struct A a[64]; unsigned long _10; struct A * _15; <bb 2>: ivtmp.12_14 = (unsigned long) &a; _10 = (unsigned long) &MEM[(void *)&a + 64B]; <bb 3>: # ivtmp.12_13 = PHI <ivtmp.12_12(3), ivtmp.12_14(2)> _15 = (struct A *) ivtmp.12_13; ivtmp.12_12 = ivtmp.12_13 + 1; if (_10 == ivtmp.12_12) goto <bb 4>; else goto <bb 3>; <bb 4>: foo (&a, 64); a ={v} {CLOBBER}; return; }