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