From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13174 invoked by alias); 23 Apr 2012 16:36:54 -0000 Received: (qmail 12700 invoked by uid 22791); 23 Apr 2012 16:36:52 -0000 X-SWARE-Spam-Status: No, hits=-3.6 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00,LOTS_OF_MONEY,TW_BG 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, 23 Apr 2012 16:36:31 +0000 From: "steven at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/53087] New: Poor code for conversion from _Bool to int Date: Mon, 23 Apr 2012 16:36:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: steven at gcc dot gnu.org 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: 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: 2012-04/txt/msg01976.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53087 Bug #: 53087 Summary: Poor code for conversion from _Bool to int Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassigned@gcc.gnu.org ReportedBy: steven@gcc.gnu.org Consider this test case: #define ONEUL (1UL) int foo (long unsigned int a) { _Bool b; long unsigned int cst, csui; if (a > 27) goto return_zero; /*cst = 217579583UL;*/ cst = (ONEUL << 0) | (ONEUL << 1) | (ONEUL << 2) | (ONEUL << 3) | (ONEUL << 4) | (ONEUL << 5) | (ONEUL << 19) | (ONEUL << 20) | (ONEUL << 21) | (ONEUL << 22) | (ONEUL << 23) | (ONEUL << 26) | (ONEUL << 27); csui = (ONEUL << a); b = ((csui & cst) != 0); if (b) return 1; else return 0; return_zero: return 0; } On powerpc64, with GCC trunk r186580, the code generated for this example is: foo: .quad .L.foo,.TOC.@tocbase,0 .previous .type foo, @function .L.foo: cmpldi 7,3,27 bgt 7,.L3 li 10,1 lis 9,0xcf8 sld 3,10,3 ori 9,9,63 and. 10,3,9 mfcr 9 rlwinm 9,9,3,1 xori 3,9,1 blr .p2align 4,,15 .L3: .L2: li 3,0 blr The poor code results from PHI-OPT which converts away the if() statement. The .149t.optimized dump looks like this: ;; Function foo (foo, funcdef_no=0, decl_uid=1996, cgraph_uid=0) foo (long unsigned int a) { _Bool D.2013; long unsigned int csui; int D.2008; long unsigned int D.2005; int D.2004; : if (a_2(D) > 27) goto (return_zero); else goto ; : D.2004_3 = (int) a_2(D); csui_4 = 1 << D.2004_3; D.2005_5 = csui_4 & 217579583; D.2013_7 = D.2005_5 != 0; D.2008_8 = (int) D.2013_7; # D.2008_1 = PHI return_zero: return D.2008_1; } The last statement in and the PHI are expanded as follows (compiled with -fno-tree-ter to make it easier to see as what RTL each statement expanded to): ;; D.2013_7 = D.2005_5 != 0; (insn 15 14 16 (set (reg:CC 134) (compare:CC (reg:DI 123 [ D.2005 ]) (const_int 0 [0]))) t.c:16 -1 (nil)) (insn 16 15 17 (set (reg:DI 135) (eq:DI (reg:CC 134) (const_int 0 [0]))) t.c:16 -1 (nil)) (insn 17 16 18 (set (reg:SI 133) (subreg:SI (reg:DI 135) 4)) t.c:16 -1 (nil)) (insn 18 17 19 (set (reg:QI 132) (subreg:QI (reg:SI 133) 3)) t.c:16 -1 (nil)) (insn 19 18 20 (set (reg:SI 136) (xor:SI (subreg:SI (reg:QI 132) 0) (const_int 1 [0x1]))) t.c:16 -1 (nil)) (insn 20 19 0 (set (reg:DI 124 [ D.2013+-7 ]) (zero_extend:DI (subreg:QI (reg:SI 136) 3))) t.c:16 -1 (nil)) ;; D.2008_8 = (int) D.2013_7; (insn 21 20 0 (set (reg:DI 120 [ D.2008+-4 ]) (sign_extend:DI (subreg/s/u:SI (reg:DI 124 [ D.2013+-7 ]) 4))) t.c:17 -1 (nil)) This is a target problem, because i686, x86_64, mips, and arm all generate much better code for this example, for example: MIPS: foo: .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0 .mask 0x00000000,0 .fmask 0x00000000,0 .set noreorder .set nomacro sltu $2,$4,28 beq $2,$0,$L3 nop li $2,1 # 0x1 sll $4,$2,$4 li $2,217579520 # 0xcf80000 addiu $2,$2,63 and $2,$4,$2 j $31 sltu $2,$0,$2 $L3: $L2 = . j $31 move $2,$0 ARM: foo: @ Function supports interworking. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. cmp r0, #27 bhi .L3 mov r3, #1 mov r0, r3, asl r0 ldr r3, .L5 and r3, r0, r3 adds r0, r3, #0 movne r0, #1 bx lr .L3: .L2: mov r0, #0 bx lr .L6: .align 2 .L5: .word 217579583