[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