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

           Summary: -O2 incorrectly swaps overlapping memory accesses
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: arthur.j.odw...@gmail.com


Created attachment 24776
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24776
Output of "ajo-gcc -w -O1 test.c -v"

This failure reproduces for me with svn revision 176128 (2011-07-10). I'm on
Ubuntu 10.10, x86-64. It looks like bug 36043 may be related.

cat >test.c <<EOF
static volatile struct S0 {
    short f3[9];
    unsigned f8 : 15;
} s = {1};
static unsigned short sh = 0x1234;

struct S0 a, b;
int vi = 0;

void func_4() {
    s.f8 |= 1;
    sh = 15;
    if (vi) a = b;
}

int main() {
    func_4();
    printf("%hx\n", sh);
    return 0;
}
EOF
gcc -w -O1 test.c ; ./a.out
gcc -w -O2 test.c ; ./a.out

With -O1, we correctly print "f".  With -O2, we incorrectly print "1234".

With -O1 we have the following assembly code:
[...]
    movq    s+16(%rip), %rax
    andq    $-2147418113, %rax
    orq    %rdx, %rax
    movq    %rax, s+16(%rip)
    movw    $15, sh(%rip)
[...]

With -O2 the scheduler has incorrectly swapped the movw into the middle of the
volatile struct access:
[...]
    movq    s+16(%rip), %rdx
    movq    s+16(%rip), %rax
    movw    $15, sh(%rip)
    andl    $2147352576, %edx
    andq    $-2147418113, %rax
    orq    $65536, %rdx
    orq    %rdx, %rax
    movq    %rax, s+16(%rip)
[...]


This test case is reduced from the output of Csmith 2.1.0 (git hash 01aa8b04,
https://github.com/Quuxplusone/csmith/), using the following command line:
csmith --paranoid --no-longlong --no-pointers --no-arrays --no-jumps
--no-consts --volatiles --checksum --no-divs --no-muls --bitfields
--packed-struct -s 320690328

Reply via email to