From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15850 invoked by alias); 3 Oct 2011 19:28:11 -0000 Received: (qmail 15840 invoked by uid 22791); 3 Oct 2011 19:28:10 -0000 X-SWARE-Spam-Status: No, hits=-2.8 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00,LOTS_OF_MONEY,TW_FC X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 03 Oct 2011 19:27:56 +0000 From: "mikpe at it dot uu.se" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/50588] gcc produce bad inlined code with -march=athlon -O2 Date: Mon, 03 Oct 2011 19:28:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: mikpe at it dot uu.se X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2011-10/txt/msg00127.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50588 --- Comment #13 from Mikael Pettersson 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