From 9373a81e53ce5f9f2c06c4209b8b886605aece08 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Wed, 10 Aug 2005 20:51:12 +0000 Subject: [PATCH] Add new node, SELECT_CC. This node is for targets that don't natively implement SELECT. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22755 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 13 ++++++ include/llvm/CodeGen/SelectionDAGNodes.h | 10 ++++- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 53 ++++++++++++++++++++++- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 3 +- 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 68f943046a5..b84b9f25c7d 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -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. diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 898041d6b16..d1273bc1ba1 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -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 diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 13fc5a656ba..fc92933643a 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -362,7 +362,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { std::map::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(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())) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 549b48042f9..a20c5176308 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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";