[llvm-commits] [llvm] r61426 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/bt.ll

Chris Lattner sabre at nondot.org
Wed Dec 24 21:34:38 PST 2008


Author: lattner
Date: Wed Dec 24 23:34:37 2008
New Revision: 61426

URL: http://llvm.org/viewvc/llvm-project?rev=61426&view=rev
Log:
Add a simple pattern for matching 'bt'.

Added:
    llvm/trunk/test/CodeGen/X86/bt.ll
Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=61426&r1=61425&r2=61426&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Dec 24 23:34:37 2008
@@ -5017,16 +5017,48 @@
 
 SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
   assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
-  SDValue Cond;
   SDValue Op0 = Op.getOperand(0);
   SDValue Op1 = Op.getOperand(1);
-  SDValue CC = Op.getOperand(2);
-  bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
+  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
+  
+  // Lower (X & (1 << N)) == 0 to BT.
+  // Lower ((X >>u N) & 1) != 0 to BT.
+  // Lower ((X >>s N) & 1) != 0 to BT.
+  // FIXME: Is i386 or later or available only on some chips?
+  if (Op0.getOpcode() == ISD::AND && Op1.getOpcode() == ISD::Constant &&
+      Op0.getOperand(1).getOpcode() == ISD::Constant &&
+      (CC == ISD::SETEQ || CC == ISD::SETNE)) {
+    ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op0.getOperand(1));
+    ConstantSDNode *CmpRHS = cast<ConstantSDNode>(Op1);
+    SDValue AndLHS = Op0.getOperand(0);
+    if (CmpRHS->getZExtValue() == 0 && AndRHS->getZExtValue() == 1 &&
+        AndLHS.getOpcode() == ISD::SRL) {
+      SDValue LHS = AndLHS.getOperand(0);
+      SDValue RHS = AndLHS.getOperand(1);
+
+      // If LHS is i8, promote it to i16 with any_extend.  There is no i8 BT
+      // instruction.  Since the shift amount is in-range-or-undefined, we know
+      // that doing a bittest on the i16 value is ok.  We extend to i32 because
+      // the encoding for the i16 version is larger than the i32 version.
+      if (LHS.getValueType() == MVT::i8)
+        LHS = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, LHS);
+
+      // If the operand types disagree, extend the shift amount to match.  Since
+      // BT ignores high bits (like shifts) we can use anyextend.
+      if (LHS.getValueType() != RHS.getValueType())
+        RHS = DAG.getNode(ISD::ANY_EXTEND, LHS.getValueType(), RHS);
+      
+      SDValue BT = DAG.getNode(X86ISD::BT, MVT::i32, LHS, RHS);
+      unsigned Cond = CC == ISD::SETEQ ? X86::COND_NC : X86::COND_C;
+      return DAG.getNode(X86ISD::SETCC, MVT::i8, 
+                         DAG.getConstant(Cond, MVT::i8), BT);
+    }
+  }
 
-  unsigned X86CC = TranslateX86CC(cast<CondCodeSDNode>(CC)->get(), isFP,
-                                  Op0, Op1, DAG);
+  bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
+  unsigned X86CC = TranslateX86CC(CC, isFP, Op0, Op1, DAG);
     
-  Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Op0, Op1);
+  SDValue Cond = DAG.getNode(X86ISD::CMP, MVT::i32, Op0, Op1);
   return DAG.getNode(X86ISD::SETCC, MVT::i8,
                      DAG.getConstant(X86CC, MVT::i8), Cond);
 }
@@ -5219,12 +5251,15 @@
 
   if (Cond.getOpcode() == ISD::SETCC)
     Cond = LowerSETCC(Cond, DAG);
+#if 0
+  // FIXME: LowerXALUO doesn't handle these!!
   else if (Cond.getOpcode() == X86ISD::ADD  ||
            Cond.getOpcode() == X86ISD::SUB  ||
            Cond.getOpcode() == X86ISD::SMUL ||
            Cond.getOpcode() == X86ISD::UMUL)
     Cond = LowerXALUO(Cond, DAG);
-
+#endif
+  
   // If condition flag is set by a X86ISD::CMP, then use it as the condition
   // setting operand in place of the X86ISD::SETCC.
   if (Cond.getOpcode() == X86ISD::SETCC) {
@@ -5232,7 +5267,8 @@
 
     SDValue Cmp = Cond.getOperand(1);
     unsigned Opc = Cmp.getOpcode();
-    if (isX86LogicalCmp(Opc)) {
+    // FIXME: WHY THE SPECIAL CASING OF LogicalCmp??
+    if (isX86LogicalCmp(Opc) || Opc == X86ISD::BT) {
       Cond = Cmp;
       addTest = false;
     } else {
@@ -5240,8 +5276,8 @@
       default: break;
       case X86::COND_O:
       case X86::COND_C:
-        // These can only come from an arithmetic instruction with overflow, e.g.
-        // SADDO, UADDO.
+        // These can only come from an arithmetic instruction with overflow,
+        // e.g. SADDO, UADDO.
         Cond = Cond.getNode()->getOperand(1);
         addTest = false;
         break;

Added: llvm/trunk/test/CodeGen/X86/bt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/bt.ll?rev=61426&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/bt.ll (added)
+++ llvm/trunk/test/CodeGen/X86/bt.ll Wed Dec 24 23:34:37 2008
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | llc | grep btl
+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-darwin8"
+
+define void @test2(i32 %x, i32 %n) nounwind {
+entry:
+	%tmp29 = lshr i32 %x, %n		; <i32> [#uses=1]
+	%tmp3 = and i32 %tmp29, 1		; <i32> [#uses=1]
+	%tmp4 = icmp eq i32 %tmp3, 0		; <i1> [#uses=1]
+	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
+
+bb:		; preds = %entry
+	call void @foo()
+	ret void
+
+UnifiedReturnBlock:		; preds = %entry
+	ret void
+}
+
+declare void @foo()





More information about the llvm-commits mailing list