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;
}