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

Reply via email to