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;

}

Reply via email to