mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Don't emit a bit test if there is only one case the test can yield false. A simple SETNE is sufficient.
llvm-svn: 135126
This commit is contained in:
parent
1856a523ea
commit
1cab6179ab
@ -1727,7 +1727,8 @@ void SelectionDAGBuilder::visitBitTestCase(BitTestBlock &BB,
|
||||
SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), getCurDebugLoc(),
|
||||
Reg, VT);
|
||||
SDValue Cmp;
|
||||
if (CountPopulation_64(B.Mask) == 1) {
|
||||
unsigned PopCount = CountPopulation_64(B.Mask);
|
||||
if (PopCount == 1) {
|
||||
// Testing for a single bit; just compare the shift count with what it
|
||||
// would need to be to shift a 1 bit in that position.
|
||||
Cmp = DAG.getSetCC(getCurDebugLoc(),
|
||||
@ -1735,6 +1736,13 @@ void SelectionDAGBuilder::visitBitTestCase(BitTestBlock &BB,
|
||||
ShiftOp,
|
||||
DAG.getConstant(CountTrailingZeros_64(B.Mask), VT),
|
||||
ISD::SETEQ);
|
||||
} else if (PopCount == BB.Range) {
|
||||
// There is only one zero bit in the range, test for it directly.
|
||||
Cmp = DAG.getSetCC(getCurDebugLoc(),
|
||||
TLI.getSetCCResultType(VT),
|
||||
ShiftOp,
|
||||
DAG.getConstant(CountTrailingOnes_64(B.Mask), VT),
|
||||
ISD::SETNE);
|
||||
} else {
|
||||
// Make desired shift
|
||||
SDValue SwitchVal = DAG.getNode(ISD::SHL, getCurDebugLoc(), VT,
|
||||
|
@ -1762,7 +1762,6 @@ case it choses instead to keep the max operation obvious.
|
||||
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
Switch lowering generates less than ideal code for the following switch:
|
||||
define void @a(i32 %x) nounwind {
|
||||
entry:
|
||||
switch i32 %x, label %if.end [
|
||||
@ -1783,19 +1782,15 @@ declare void @foo()
|
||||
Generated code on x86-64 (other platforms give similar results):
|
||||
a:
|
||||
cmpl $5, %edi
|
||||
ja .LBB0_2
|
||||
movl %edi, %eax
|
||||
movl $47, %ecx
|
||||
btq %rax, %rcx
|
||||
jb .LBB0_3
|
||||
ja LBB2_2
|
||||
cmpl $4, %edi
|
||||
jne LBB2_3
|
||||
.LBB0_2:
|
||||
ret
|
||||
.LBB0_3:
|
||||
jmp foo # TAILCALL
|
||||
|
||||
The movl+movl+btq+jb could be simplified to a cmpl+jne.
|
||||
|
||||
Or, if we wanted to be really clever, we could simplify the whole thing to
|
||||
If we wanted to be really clever, we could simplify the whole thing to
|
||||
something like the following, which eliminates a branch:
|
||||
xorl $1, %edi
|
||||
cmpl $4, %edi
|
||||
|
@ -79,3 +79,23 @@ if.end: ; preds = %entry
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
define void @test3(i32 %x) nounwind {
|
||||
; CHECK: test3:
|
||||
; CHECK: cmpl $5
|
||||
; CHECK: ja
|
||||
; CHECK: cmpl $4
|
||||
; CHECK: jne
|
||||
switch i32 %x, label %if.end [
|
||||
i32 0, label %if.then
|
||||
i32 1, label %if.then
|
||||
i32 2, label %if.then
|
||||
i32 3, label %if.then
|
||||
i32 5, label %if.then
|
||||
]
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user