http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58546
Bug ID: 58546 Summary: volatile bug and also larger code at -Os Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: regehr at cs dot utah.edu I believe that gcc r202854 for x86-64 Linux miscompiles the program below at -Os. int a; volatile char b = 1; short c[] = { 0, 0, 0, 0, 0, 0, 1 }; int main() { for (; a >= 0; a--) c[6]++; return 0; } The compiler output is: main: movl a(%rip), %eax movl %eax, %ecx addl c+12(%rip), %ecx .L2: movl %ecx, %edx subl %eax, %edx testl %eax, %eax js .L5 decl %eax jmp .L2 .L5: movl %eax, a(%rip) movw %dx, c+12(%rip) xorl %eax, %eax ret I believe that 32-bit load of c[6] at c+12(%rip) is incorrect as it causes a spurious load from volatile variable b. This kind of spurious load can cause problems for low-level code where reads have side effects such as a page fault or hardware register access. In contrast, the -O2 code is smaller and properly accesses c[6] using a 16-bit load and store: main: movl a(%rip), %eax testl %eax, %eax js .L2 addw c+12(%rip), %ax movl $-1, a(%rip) addl $1, %eax movw %ax, c+12(%rip) .L2: xorl %eax, %eax ret