[LLVMbugs] [Bug 3761] New: inefficient codegen of x86 brcond/ select emits unnecessary comparison instructions

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Mon Mar 9 01:53:56 PDT 2009


http://llvm.org/bugs/show_bug.cgi?id=3761

           Summary: inefficient codegen of x86 brcond/select emits
                    unnecessary comparison instructions
           Product: libraries
           Version: 2.5
          Platform: PC
               URL: http://pastie.org/private/fofieg4h6gegqqkvxzynnq
        OS/Version: All
            Status: NEW
          Keywords: code-quality, quality-of-implementation
          Severity: enhancement
          Priority: P2
         Component: Backend: X86
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: just.s0m3.guy+llvmbugzilla at gmail.com
                CC: llvmbugs at cs.uiuc.edu


The custom lowering code for BRCOND and SELECT in the X86 target backend
(X86ISelLowering.cpp) seems to always insert a comparison instruction.

This is not always necessary. If the conditional branch directly follows the
arithmetic operation, which sets the EFLAGS (such as ADD, SUB,...), which are
applicable to the specific condition which must be checked, there is no reason
to emit an additional comparison.

In the worst case, the additional comparison causes register moves and
copy-to-registers to be emitted, further bloating the output code.

For example, take the following c function:
//branchtest.c:
int main(){
        int x = 1;
        int y = 10;
        x = x + y;
        if(x>0)
                return 1;
        else
                return 2;
}

Using llvm-gcc4.2-2.5 (release), the following llvm code is generated:
//branchtest.bc (gcc -c --emit-llvm branching.c -o branching.bc; llvm-dis <
branching.bc)
; ModuleID = '<stdin>'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-unknown-linux-gnu"

define i32 @main() nounwind {
entry:
        %retval = alloca i32            ; <i32*> [#uses=2]
        %y = alloca i32         ; <i32*> [#uses=2]
        %x = alloca i32         ; <i32*> [#uses=4]
        %0 = alloca i32         ; <i32*> [#uses=3]
        %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
        store i32 1, i32* %x, align 4
        store i32 10, i32* %y, align 4
        %1 = load i32* %x, align 4              ; <i32> [#uses=1]
        %2 = load i32* %y, align 4              ; <i32> [#uses=1]
        %3 = add i32 %1, %2             ; <i32> [#uses=1]
        store i32 %3, i32* %x, align 4
        %4 = load i32* %x, align 4              ; <i32> [#uses=1]
        %5 = icmp sgt i32 %4, 0         ; <i1> [#uses=1]
        br i1 %5, label %bb, label %bb1

bb:             ; preds = %entry
        store i32 1, i32* %0, align 4
        br label %bb2

bb1:            ; preds = %entry
        store i32 2, i32* %0, align 4
        br label %bb2

bb2:            ; preds = %bb1, %bb
        %6 = load i32* %0, align 4              ; <i32> [#uses=1]
        store i32 %6, i32* %retval, align 4
        br label %return

return:         ; preds = %bb2
        %retval3 = load i32* %retval            ; <i32> [#uses=1]
        ret i32 %retval3
}

The problem occurs when trying to compile this to native x86, using llc:
/branching.s (llc -march=x86 -f branching.bc):
        .file   "branching/branching.bc"


        .text
        .align  16
        .globl  main
        .type   main, at function
main:
        subl    $16, %esp
        movl    $1, 4(%esp)
        movl    $10, 8(%esp)
        movl    4(%esp), %eax
        addl    $10, %eax
        movl    %eax, 4(%esp)                  
        testl   %eax, %eax                        <==== this test is
unnecessary. the preceding addl sets the 
                                                                               
    flags correctly
        jg      .LBB1_4 # bb
.LBB1_1:        # bb1
        movl    $2, (%esp)
.LBB1_2:        # bb2
        movl    (%esp), %eax
        movl    %eax, 12(%esp)
.LBB1_3:        # return
        movl    12(%esp), %eax
        addl    $16, %esp
        ret
.LBB1_4:        # bb
        movl    $1, (%esp)
        jmp     .LBB1_2 # bb2
        .size   main, .-main

        .section        .note.GNU-stack,"", at progbits

Furthermore, it is unclear how exactly the desired functionality should be
implemented, as there don't appear to be an working examples.


-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list