Add new node, SELECT_CC. This node is for targets that don't natively
authorNate Begeman <natebegeman@mac.com>
Wed, 10 Aug 2005 20:51:12 +0000 (20:51 +0000)
committerNate Begeman <natebegeman@mac.com>
Wed, 10 Aug 2005 20:51:12 +0000 (20:51 +0000)
implement SELECT.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22755 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAG.h
include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 68f943046a52b152e31c67cbc1ce942ed516ddc7..b84b9f25c7d2027c5f927edeccb69f6303157b56 100644 (file)
@@ -183,6 +183,19 @@ public:
                      ISD::CondCode Cond) {
     return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond));
   }
+
+  /// getSelectCC - Helper function to make it easier to build SelectCC's if you
+  /// just have an ISD::CondCode instead of an SDOperand.
+  ///
+  SDOperand getSelectCC(SDOperand LHS, SDOperand RHS,
+                        SDOperand True, SDOperand False, ISD::CondCode Cond) {
+    MVT::ValueType VT = True.getValueType();
+    assert(LHS.getValueType() == RHS.getValueType() &&
+           "LHS and RHS of condition must have same type!");
+    assert(True.getValueType() == False.getValueType() &&
+           "True and False arms of SelectCC must have same type!");
+    return getNode(ISD::SELECT_CC, VT, LHS, RHS, True, False,getCondCode(Cond));
+  }
   
   /// getLoad - Loads are not normal binary operators: their result type is not
   /// determined by their operands, and they produce a value AND a token chain.
index 898041d6b161caaacbabba0af47616cc82529172..d1273bc1ba14ce4a9700ea67041aad5b40d26801 100644 (file)
@@ -103,8 +103,14 @@ namespace ISD {
     // Counting operators
     CTTZ, CTLZ, CTPOP,
 
-    // Select operator.
-    SELECT,
+    // Select
+    SELECT, 
+    
+    // Select with condition operator - This selects between a true value and 
+    // a false value (ops #2 and #3) based on the boolean result of comparing
+    // the lhs and rhs (ops #0 and #1) of a conditional expression with the 
+    // condition code in op #4, a CondCodeSDNode.
+    SELECT_CC,
 
     // SetCC operator - This evaluates to a boolean (i1) true value if the
     // condition is true.  The operands to this are the left and right operands
index 13fc5a656ba281ab497db3b3a5c460f138678419..fc92933643a01e6fa762808838dbd87c38d36bb7 100644 (file)
@@ -362,7 +362,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
   std::map<SDOperand, SDOperand>::iterator I = LegalizedNodes.find(Op);
   if (I != LegalizedNodes.end()) return I->second;
 
-  SDOperand Tmp1, Tmp2, Tmp3;
+  SDOperand Tmp1, Tmp2, Tmp3, Tmp4;
 
   SDOperand Result = Op;
 
@@ -911,6 +911,17 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
 
     switch (TLI.getOperationAction(Node->getOpcode(), Tmp2.getValueType())) {
     default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Expand:
+      if (Tmp1.getOpcode() == ISD::SETCC) {
+        Result = DAG.getSelectCC(Tmp1.getOperand(0), Tmp1.getOperand(1), 
+                              Tmp2, Tmp3,
+                              cast<CondCodeSDNode>(Tmp1.getOperand(2))->get());
+      } else {
+        Result = DAG.getSelectCC(Tmp1, 
+                                 DAG.getConstant(0, Tmp1.getValueType()),
+                                 Tmp2, Tmp3, ISD::SETNE);
+      }
+      break;
     case TargetLowering::Legal:
       if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
           Tmp3 != Node->getOperand(2))
@@ -938,6 +949,29 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     }
     }
     break;
+  case ISD::SELECT_CC:
+    Tmp3 = LegalizeOp(Node->getOperand(2));   // True
+    Tmp4 = LegalizeOp(Node->getOperand(3));   // False
+    
+    if (getTypeAction(Node->getOperand(0).getValueType()) == Legal) {
+      Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
+      Tmp2 = LegalizeOp(Node->getOperand(1));   // RHS
+      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
+          Tmp3 != Node->getOperand(2) || Tmp4 != Node->getOperand(3)) {
+        Result = DAG.getNode(ISD::SELECT_CC, Node->getValueType(0), Tmp1, Tmp2, 
+                             Tmp3, Tmp4, Node->getOperand(4));
+      }
+      break;
+    } else {
+      Tmp1 = LegalizeOp(DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(),
+                                    Node->getOperand(0),  // LHS
+                                    Node->getOperand(1),  // RHS
+                                    Node->getOperand(4)));
+      Result = DAG.getSelectCC(Tmp1,
+                               DAG.getConstant(0, Tmp1.getValueType()), 
+                               Tmp3, Tmp4, ISD::SETNE);
+    }
+    break;
   case ISD::SETCC:
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
     case Legal:
@@ -1999,6 +2033,13 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
     Tmp3 = PromoteOp(Node->getOperand(2));   // Legalize the op1
     Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2, Tmp3);
     break;
+  case ISD::SELECT_CC:
+    Tmp2 = PromoteOp(Node->getOperand(2));   // True
+    Tmp3 = PromoteOp(Node->getOperand(3));   // False
+    Result = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
+                         Node->getOperand(1), Tmp2, Tmp3,
+                         Node->getOperand(4));
+    break;
   case ISD::TAILCALL:
   case ISD::CALL: {
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
@@ -2733,6 +2774,16 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     Hi = DAG.getNode(ISD::SELECT, NVT, C, LH, RH);
     break;
   }
+  case ISD::SELECT_CC: {
+    SDOperand TL, TH, FL, FH;
+    ExpandOp(Node->getOperand(2), TL, TH);
+    ExpandOp(Node->getOperand(3), FL, FH);
+    Lo = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
+                     Node->getOperand(1), TL, FL, Node->getOperand(4));
+    Hi = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
+                     Node->getOperand(1), TH, FH, Node->getOperand(4));
+    break;
+  }
   case ISD::SIGN_EXTEND: {
     SDOperand In;
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
index 549b48042f9fa50bdd07346a1cc53458cf2e2312..a20c5176308855879c9f21ffbc6e8490219b7f5b 100644 (file)
@@ -686,8 +686,6 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
   return SDOperand();
 }
 
-
-
 /// getNode - Gets or creates the specified node.
 ///
 SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) {
@@ -1702,6 +1700,7 @@ const char *SDNode::getOperationName() const {
 
   case ISD::SETCC:       return "setcc";
   case ISD::SELECT:      return "select";
+  case ISD::SELECT_CC:   return "select_cc";
   case ISD::ADD_PARTS:   return "add_parts";
   case ISD::SUB_PARTS:   return "sub_parts";
   case ISD::SHL_PARTS:   return "shl_parts";