aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp27
-rw-r--r--test/CodeGen/X86/select-no-cmov.ll14
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
+}