http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50588

--- Comment #13 from Mikael Pettersson <mikpe at it dot uu.se> 2011-10-03 
19:27:21 UTC ---
Created attachment 25404
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=25404
reduced preprocessed test case

With this reduced test case I'm seeing gcc-4.6 ifcvt hoisting trapping insns
that depend on a NULL pointer check before that pointer check when
-mtune=athlon is in effect.

> cat pr50588.c
unsigned int __attribute__((noinline,noclone)) do_try(int *fd)
{
    unsigned int bits[32];

    bits[0] = 0;
    asm("" : "=m"(bits) : "r"(bits) : "memory");

    bits[(fd ? *fd : -1) / 32U] |= 1U << ((fd ? *fd : -1) % 32U);

    return bits[0];
}

int main(void)
{
    int fd = 3;
    if (do_try(&fd) != (1U << 3))
        __builtin_abort();
    return 0;
}
> /tmp/objdir46/gcc/xgcc -B/tmp/objdir46/gcc/ -O2 -S pr50588.c ; cat pr50588.s
        .file   "pr50588.c"
        .text
        .p2align 4,,15
        .globl  do_try
        .type   do_try, @function
do_try:
.LFB0:
        .cfi_startproc
        pushl   %ebx
        .cfi_def_cfa_offset 8
        .cfi_offset 3, -8
        addl    $-128, %esp
        .cfi_def_cfa_offset 136
        movl    136(%esp), %eax
        movl    $0, (%esp)
        testl   %eax, %eax
        je      .L2

## This is OK, we're testing fd (eax) before doing anything that depends on its
value.

        movl    (%eax), %ecx
        movl    $1, %eax
        movl    %ecx, %edx
        shrl    $5, %edx
        movl    (%esp,%edx,4), %ebx
        sall    %cl, %eax
        orl     %ebx, %eax
        movl    %eax, (%esp,%edx,4)
        movl    (%esp), %eax
        subl    $-128, %esp
        .cfi_remember_state
        .cfi_def_cfa_offset 8
        popl    %ebx
        .cfi_def_cfa_offset 4
        .cfi_restore 3
        ret
        .p2align 4,,7
        .p2align 3
.L2:
        .cfi_restore_state
        movl    536870908(%esp), %ebx

### This would obviously fail at runtime, but as fd != NULL it won't be
executed.

        movl    $-2147483648, %eax
        movl    $134217727, %edx
        orl     %ebx, %eax
        movl    %eax, (%esp,%edx,4)
        movl    (%esp), %eax
...
> /tmp/objdir46/gcc/xgcc -B/tmp/objdir46/gcc/ -mtune=athlon -O2 -S pr50588.c ; 
> cat pr50588.s
        .file   "pr50588.c"
        .text
        .p2align 4,,15
        .globl  do_try
        .type   do_try, @function
do_try:
.LFB0:
        .cfi_startproc
        pushl   %ebx
        .cfi_def_cfa_offset 8
        .cfi_offset 3, -8
        movl    $134217727, %edx
        movl    $-2147483648, %eax
        addl    $-128, %esp
        .cfi_def_cfa_offset 136
        movl    136(%esp), %ecx
        movl    $0, (%esp)
        movl    536870908(%esp), %ebx

## This is broken.  Trapping insns from the fd == NULL case have been hoisted
above the fd == NULL check.  The movl above does segfault at runtime.

        testl   %ecx, %ecx
        je      .L3
        movl    (%ecx), %ecx
        movl    $1, %eax
        movl    %ecx, %edx
        sall    %cl, %eax
        shrl    $5, %edx
        movl    (%esp,%edx,4), %ebx
.L3:
        orl     %ebx, %eax
        movl    %eax, (%esp,%edx,4)
        movl    (%esp), %eax
        subl    $-128, %esp
        .cfi_def_cfa_offset 8
        popl    %ebx
        .cfi_def_cfa_offset 4
        .cfi_restore 3
        ret
        .cfi_endproc

Reply via email to