This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/53087] New: Poor code for conversion from _Bool to int


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;

<bb 2>:
  if (a_2(D) > 27)
    goto <bb 4> (return_zero);
  else
    goto <bb 3>;

<bb 3>:
  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 <D.2008_8(3), 0(2)>
return_zero:
  return D.2008_1;

}


The last statement in <bb 3> 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]