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: [email protected]
ReportedBy: [email protected]
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