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 optimization/15187] New: Inefficient if optimization with -O2 -ffast-math


This testcase compiles with '-O2 -ffast-math' into extremely inefficient asm code:
double test(double x) {
        if (x > 0.0)
                return cos(x);
        else
                return sin(x);
}

--cut here--
test:
        pushl   %ebp
        movl    %esp, %ebp
        fldl    8(%ebp)
        fcoml   .LC1
        fnstsw  %ax
        fld     %st(0)
        fcos
        sahf
        ja      .L6
        fstp    %st(0)
        fsin
        jmp     .L1
        .p2align 4,,7
.L6:
        fstp    %st(1)
.L1:
        popl    %ebp
        ret
--cut here--

It will _always_ call fcos instruction, and - depending on input - overwrite
output of fcos with output of fsin instruction. This problem is not fsin/fcos
specific.

The problem is in ifcvt.c, find_if_case_1() function. Around line 2889, there is
a condition:
  /* THEN is small.  */
  if (count_bb_insns (then_bb) > BRANCH_COST)
    return FALSE;

This condition would prevent moving 'else' BB before 'if', if then_bb is not
small. 'Small' means a couple of instructions with default BRANCH_COST (= 1).

However, if an instruction is UNSPEC_*, this instruction can last hundred of
cycles (as it is case with fsin or fcos), but it is still _one_ RTL instruction.
So the case above is not triggered, and fcos is moved before 'if'. 

The situation is even worser with '-O2 -ffast-math -march=i686'. fsin and fcos
are called every time...

test:
        pushl   %ebp
        movl    %esp, %ebp
        fldl    8(%ebp)
        fldz
        fld     %st(1)
        fld     %st(2)
        fxch    %st(1)
        fcos
        fxch    %st(3)
        popl    %ebp
        fcomip  %st(2), %st
        fstp    %st(1)
        fsin
        fcmovnbe        %st(1), %st
        fstp    %st(1)
        ret

-- 
           Summary: Inefficient if optimization with -O2 -ffast-math
           Product: gcc
           Version: 3.5.0
            Status: UNCONFIRMED
          Severity: critical
          Priority: P2
         Component: optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: uros at kss-loka dot si
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


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


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