[Bug target/81365] [7/8 Regression] GCC miscompiles swap

glisse at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Jul 9 20:48:00 GMT 2017


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81365

Marc Glisse <glisse at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-07-09
            Summary|GCC miscompiles swap        |[7/8 Regression] GCC
                   |                            |miscompiles swap
     Ever confirmed|0                           |1

--- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> ---
phiprop seems responsible, it changes

+  <bb 9> [34.00%]:
+  x.head[0] = MEM[(const struct Lit &)&x + 12];
+
   <bb 5> [99.97%]:
-  # it_16 = PHI <&x.tail(2), &MEM[(void *)&x + 16B](3)>
+  # it_16 = PHI <&x.tail(9), &MEM[(void *)&x + 16B](10)>
   t$rep_15 = MEM[(struct Foo *)&x];
-  x.head[0] = MEM[(const struct Lit &)it_16];
   MEM[(struct Lit *)it_16] = t$rep_15;

but x.head[0] and MEM[(struct Foo *)&x] are the same location...


extern "C" int puts(const char *);
struct Lit {
  unsigned rep;
};

struct Foo {
  Foo(const Lit* lits) {
    __builtin_memcpy(head , lits, 3*sizeof(Lit));
    __builtin_memcpy(tail , lits + 3, sizeof(Lit));
    __builtin_memset(tail+1 , 0, sizeof(Lit));
  }
  bool swapToHead(unsigned what){
    Lit* it = tail;
    if (it->rep == what || (++it)->rep == what) {
      Lit t(head[0]);
      head[0]=*it;
      *it=t;
      return true;
    }
    return false;
  }
  Lit head[3];
  Lit tail[2];
};

int main() {
  Lit lits[] = {4,8,12,18};
  Foo x(lits);
  x.swapToHead(18) || (puts("1"),__builtin_abort(),false);
  x.swapToHead( 4) || (puts("2"),__builtin_abort(),false);
  return 0;
}


More information about the Gcc-bugs mailing list