The following testcase is miscompiled on {powerpc,i386,x86_64}-redhat-linux
(well, any other for which an __asm is written).

extern void abort (void);

unsigned short v = 0x0300;

void
foo (unsigned short *p)
{
  *p = v;
}

int
bar (void)
{
  unsigned short x;
  volatile unsigned short *z;
  foo (&x);
  const unsigned int y = x;
  z = &x;
#ifdef __powerpc__
  __asm __volatile ("sthbrx %1,0,%2" : "=m" (*z) : "r" (y), "r" (z));
#elif defined __i386__ || defined __x86_64__
  __asm __volatile ("movb %b1,1(%2); movb %h1,(%2)" : "=m" (*z) : "r" (y), "r"
(z));
#endif
  return (x & 1) == 0;
}

int
main (void)
{
  if (bar ())
    abort ();
  return 0;
}

In final_cleanup, bar is:
bar ()
{
  const unsigned intD.3 yD.1507;
  short unsigned intD.8 xD.1505;

  # BLOCK 0
  # PRED: ENTRY [100.0%]  (fallthru,exec)
  #   xD.1505_11 = V_MAY_DEF <xD.1505_1>;
  foo (&xD.1505);
  yD.1507 = (const unsigned intD.3) xD.1505;
  #   xD.1505_12 = V_MAY_DEF <xD.1505_11>;
  __asm__ __volatile__("movb %b1,1(%2); movb %h1,(%2)":"=m" xD.1505:"r" yD.1507,
"r" &xD.1505);
  return (intD.0) (yD.1507 ^ 1) & 1;
  # SUCC: EXIT [100.0%]

}

which is wrong, it must reread xD.1505 instead of assuming xD.1505 == yD.1507.

-- 
           Summary: asm "=m" not taken into account
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: tree-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: jakub at gcc dot gnu dot org
                CC: gcc-bugs at gcc dot gnu dot org,mikpe at csd dot uu dot
                    se


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20210

Reply via email to