http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49893
Summary: [4.7 Regression] -O3 generates wrong code for volatile Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: hjl.to...@gmail.com On Linux/x86-64, GCC 4.7 compiles this test into an infinite loop: [hjl@gnu-mic-2 time]$ cat /tmp/x.c extern unsigned int alarm (unsigned int __seconds) __attribute__ ((__nothrow__)); typedef void (*__sighandler_t) (int); extern __sighandler_t signal (int __sig, __sighandler_t __handler) __attribute__ ((__nothrow__)); typedef long int clock_t; extern clock_t clock (void) __attribute__ ((__nothrow__)); volatile int gotit = 0; static void alarm_handler (int signal) { gotit = 1; } int main (int argc, char ** argv) { clock_t start, stop; if (signal(14, alarm_handler) == ((__sighandler_t) -1)) { return -1; } alarm(1); start = clock (); while (!gotit); stop = clock (); return start - stop; } [hjl@gnu-mic-2 time]$ /usr/gcc-4.7.0-x32/bin/gcc -O3 /tmp/x.c [hjl@gnu-mic-2 time]$ ./a.out ^C [hjl@gnu-mic-2 time]$ It forgot "gotit" was marked volatile and might change. main: .LFB1: .cfi_startproc pushq %rbx .cfi_def_cfa_offset 16 .cfi_offset 3, -16 movl $alarm_handler, %esi movl $14, %edi call signal cmpq $-1, %rax je .L3 movl $1, %edi call alarm call clock movq %rax, %rbx movl gotit(%rip), %eax testl %eax, %eax je .L4 call clock subl %eax, %ebx movl %ebx, %eax .L3: popq %rbx .cfi_remember_state .cfi_def_cfa_offset 8 ret .L4: .cfi_restore_state .p2align 4,,4 jmp .L4 .cfi_endproc