Implement cond ? -1 : 0 with sbb.
authorEvan Cheng <evan.cheng@apple.com>
Tue, 26 Jan 2010 02:00:44 +0000 (02:00 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 26 Jan 2010 02:00:44 +0000 (02:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94490 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/sext-i1.ll [new file with mode: 0644]

index 8883064df999c71012128a455f714aa8f64d73a1..640bdc091ca1554140a8ee31e5137fa16a63c48d 100644 (file)
@@ -3220,6 +3220,14 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
                        NegOne, DAG.getConstant(0, VT),
                        cast<CondCodeSDNode>(N0.getOperand(2))->get(), true);
     if (SCC.getNode()) return SCC;
+    if (!LegalOperations ||
+        TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultType(VT)))
+      return DAG.getNode(ISD::SELECT, N->getDebugLoc(), VT,
+                         DAG.getSetCC(N->getDebugLoc(),
+                                      TLI.getSetCCResultType(VT),
+                                      N0.getOperand(0), N0.getOperand(1),
+                                 cast<CondCodeSDNode>(N0.getOperand(2))->get()),
+                         NegOne, DAG.getConstant(0, VT));
   }
   
   
index aae17a8cf1bb77536b5a3750510ff76d699d15e2..e53f6b7525bbb992bfc3e6f52866b7b82ad56ad7 100644 (file)
@@ -5965,6 +5965,29 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
       Cond = NewCond;
   }
 
+  // (select (x == 0), -1, 0) -> (sign_bit (x - 1))
+  SDValue Op1 = Op.getOperand(1);
+  SDValue Op2 = Op.getOperand(2);
+  if (Cond.getOpcode() == X86ISD::SETCC &&
+      cast<ConstantSDNode>(Cond.getOperand(0))->getZExtValue() == X86::COND_E) {
+    SDValue Cmp = Cond.getOperand(1);
+    if (Cmp.getOpcode() == X86ISD::CMP) {
+      ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(Op1);
+      ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(Op2);
+      ConstantSDNode *RHSC =
+        dyn_cast<ConstantSDNode>(Cmp.getOperand(1).getNode());
+      if (N1C && N1C->isAllOnesValue() &&
+          N2C && N2C->isNullValue() &&
+          RHSC && RHSC->isNullValue()) {
+        SDValue CmpOp0 = Cmp.getOperand(0);
+        Cmp = DAG.getNode(X86ISD::CMP, dl, Op.getValueType(),
+                          CmpOp0, DAG.getConstant(1, CmpOp0.getValueType()));
+        return DAG.getNode(X86ISD::SETCC_CARRY, dl, Op.getValueType(),
+                           DAG.getConstant(X86::COND_B, MVT::i8), Cmp);
+      }
+    }
+  }
+
   // Look pass (and (setcc_carry (cmp ...)), 1).
   if (Cond.getOpcode() == ISD::AND &&
       Cond.getOperand(0).getOpcode() == X86ISD::SETCC_CARRY) {
@@ -6017,10 +6040,10 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
     Cond = EmitTest(Cond, X86::COND_NE, DAG);
   }
 
-  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
   // X86ISD::CMOV means set the result (which is operand 1) to the RHS if
   // condition is true.
-  SDValue Ops[] = { Op.getOperand(2), Op.getOperand(1), CC, Cond };
+  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
+  SDValue Ops[] = { Op2, Op1, CC, Cond };
   return DAG.getNode(X86ISD::CMOV, dl, VTs, Ops, array_lengthof(Ops));
 }
 
diff --git a/test/CodeGen/X86/sext-i1.ll b/test/CodeGen/X86/sext-i1.ll
new file mode 100644 (file)
index 0000000..b0771b0
--- /dev/null
@@ -0,0 +1,22 @@
+; RUN: llc < %s -march=x86 | FileCheck %s
+; rdar://7573216
+
+define i32 @t1(i32 %x) nounwind readnone ssp {
+entry:
+; CHECK: t1:
+; CHECK: cmpl $1
+; CHECK: sbbl
+  %0 = icmp eq i32 %x, 0
+  %iftmp.0.0 = select i1 %0, i32 -1, i32 0
+  ret i32 %iftmp.0.0
+}
+
+define i32 @t2(i32 %x) nounwind readnone ssp {
+entry:
+; CHECK: t2:
+; CHECK: cmpl $1
+; CHECK: sbbl
+  %0 = icmp eq i32 %x, 0
+  %iftmp.0.0 = sext i1 %0 to i32
+  ret i32 %iftmp.0.0
+}