diff options
author | Chris Lattner <sabre@nondot.org> | 2009-03-13 05:22:11 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-03-13 05:22:11 +0000 |
commit | 97a29a5fee209769c52d78564ffe9dde514d5f03 (patch) | |
tree | faf14ba7ea8ee696b7a08aa3537cf772357e751c | |
parent | 0582ae99ba75a556d6ff63b254da327d32ba036f (diff) |
optimize the case of cond ? 42 : 41 and friends. This compiles the
example to:
_test:
movl 4(%esp), %eax
cmpl $41, (%eax)
setg %al
movzbl %al, %eax
orl $4294967294, %eax
ret
instead of:
movl 4(%esp), %eax
cmpl $41, (%eax)
movl $4294967294, %ecx
movl $4294967295, %eax
cmova %ecx, %eax
ret
which is smaller in code size and faster. rdar://6668608
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66868 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 27 | ||||
-rw-r--r-- | test/CodeGen/X86/select-no-cmov.ll | 14 |
2 files changed, 41 insertions, 0 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index dfa2a09098..f54b7b6f80 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -8218,6 +8218,18 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, return DAG.getNode(ISD::SHL, DL, LHS.getValueType(), Cond, DAG.getConstant(ShAmt, MVT::i8)); } + + // Optimize Cond ? cst+1 : cst -> zext(setcc(C)+cst. + if (RHSC->getAPIntValue()+1 == LHSC->getAPIntValue()) { + if (NeedsCondInvert) // Invert the condition if needed. + Cond = DAG.getNode(ISD::XOR, DL, Cond.getValueType(), Cond, + DAG.getConstant(1, Cond.getValueType())); + + // Zero extend the condition if needed. + Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, RHSC->getValueType(0), Cond); + return DAG.getNode(ISD::ADD, DL, Cond.getValueType(), Cond, + SDValue(RHSC, 0)); + } } } @@ -8263,6 +8275,21 @@ static SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG, return DCI.CombineTo(N, Cond, SDValue()); return Cond; } + + // Optimize Cond ? cst+1 : cst -> zext(setcc(C)+cst. + if (FalseC->getAPIntValue()+1 == TrueC->getAPIntValue()) { + SDValue Cond = N->getOperand(3); + Cond = DAG.getNode(X86ISD::SETCC, DL, MVT::i8, + DAG.getConstant(CC, MVT::i8), Cond); + + // Zero extend the condition if needed. + Cond = DAG.getNode(ISD::ZERO_EXTEND, DL, FalseC->getValueType(0), Cond); + Cond = DAG.getNode(ISD::ADD, DL, Cond.getValueType(), Cond, + SDValue(FalseC, 0)); + if (N->getNumValues() == 2) // Dead flag value? + return DCI.CombineTo(N, Cond, SDValue()); + return Cond; + } } } return SDValue(); diff --git a/test/CodeGen/X86/select-no-cmov.ll b/test/CodeGen/X86/select-no-cmov.ll new file mode 100644 index 0000000000..87382fe3c8 --- /dev/null +++ b/test/CodeGen/X86/select-no-cmov.ll @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llc | not grep cmov + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + +; Should compile to setcc | -2. +; rdar://6668608 +define i32 @test(i32* nocapture %P) nounwind readonly { +entry: + %0 = load i32* %P, align 4 ; <i32> [#uses=1] + %1 = icmp sgt i32 %0, 41 ; <i1> [#uses=1] + %iftmp.0.0 = select i1 %1, i32 -1, i32 -2 ; <i32> [#uses=1] + ret i32 %iftmp.0.0 +} |