aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManman Ren <mren@apple.com>2012-04-30 22:51:25 +0000
committerManman Ren <mren@apple.com>2012-04-30 22:51:25 +0000
commit16a76519a5aa0e3a351cfde8e7236119ffd8b7fb (patch)
tree97a13cf302560765c6b11772e89492122789fbc0
parent7a3afa91ad8f68428373948fc16375e99bff3c6f (diff)
X86: optimization for -(x != 0)
This patch will optimize -(x != 0) on X86 FROM cmpl $0x01,%edi sbbl %eax,%eax notl %eax TO negl %edi sbbl %eax %eax git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155853 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp16
-rw-r--r--test/CodeGen/X86/select.ll21
2 files changed, 37 insertions, 0 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 83c357d708..660a1bd0bd 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -8589,6 +8589,22 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
SDValue Y = isAllOnes(Op2) ? Op1 : Op2;
SDValue CmpOp0 = Cmp.getOperand(0);
+ // further optimization for special cases
+ // (select (x != 0), -1, 0) -> neg & sbb
+ // (select (x == 0), 0, -1) -> neg & sbb
+ if (ConstantSDNode *YC = dyn_cast<ConstantSDNode>(Y))
+ if (YC->isNullValue() &&
+ (isAllOnes(Op1) == (CondCode == X86::COND_NE))) {
+ SDVTList VTs = DAG.getVTList(CmpOp0.getValueType(), MVT::i32);
+ SDValue Neg = DAG.getNode(ISD::SUB, DL, VTs,
+ DAG.getConstant(0, CmpOp0.getValueType()),
+ CmpOp0);
+ SDValue Res = DAG.getNode(X86ISD::SETCC_CARRY, DL, Op.getValueType(),
+ DAG.getConstant(X86::COND_B, MVT::i8),
+ SDValue(Neg.getNode(), 1));
+ return Res;
+ }
+
Cmp = DAG.getNode(X86ISD::CMP, DL, MVT::i32,
CmpOp0, DAG.getConstant(1, CmpOp0.getValueType()));
Cmp = ConvertCmpIfNecessary(Cmp, DAG);
diff --git a/test/CodeGen/X86/select.ll b/test/CodeGen/X86/select.ll
index 9adf4f9c05..5730f618e4 100644
--- a/test/CodeGen/X86/select.ll
+++ b/test/CodeGen/X86/select.ll
@@ -218,3 +218,24 @@ define i32 @test14(i32 %a, i32 %b) nounwind {
; CHECK-NEXT: ret
}
+; rdar://10961709
+define i32 @test15(i32 %x) nounwind {
+entry:
+ %cmp = icmp ne i32 %x, 0
+ %sub = sext i1 %cmp to i32
+ ret i32 %sub
+; CHECK: test15:
+; CHECK: negl
+; CHECK: sbbl
+}
+
+define i32 @test16(i32 %x) nounwind {
+entry:
+ %c = icmp eq i32 %x, 0
+ %d = select i1 %c, i32 0, i32 -1
+ ret i32 %d
+; CHECK: test16:
+; CHECK: negl
+; CHECK: sbbl
+}
+