From 3ff25514ce24a521fc9524eefb257a1f5f262d84 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Thu, 14 Jul 2011 01:38:42 +0000 Subject: [PATCH] Don't emit a bit test if there is only one case the test can yield false. A simple SETNE is sufficient. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135126 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 10 +++++++++- lib/Target/README.txt | 13 ++++--------- test/CodeGen/X86/switch-bt.ll | 20 ++++++++++++++++++++ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 66b6024ba29..3a04ee1e938 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -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, diff --git a/lib/Target/README.txt b/lib/Target/README.txt index 4e382e8f8ec..4cc95340890 100644 --- a/lib/Target/README.txt +++ b/lib/Target/README.txt @@ -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 diff --git a/test/CodeGen/X86/switch-bt.ll b/test/CodeGen/X86/switch-bt.ll index 9f491d452fa..8e393422143 100644 --- a/test/CodeGen/X86/switch-bt.ll +++ b/test/CodeGen/X86/switch-bt.ll @@ -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 +} -- 2.11.0