This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/50588] gcc produce bad inlined code with -march=athlon -O2
- From: "mikpe at it dot uu.se" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 03 Oct 2011 19:27:21 +0000
- Subject: [Bug target/50588] gcc produce bad inlined code with -march=athlon -O2
- Auto-submitted: auto-generated
- References: <bug-50588-4@http.gcc.gnu.org/bugzilla/>
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