implement promotion of BR_CC operands, fixing bisort on ppc.
authorChris Lattner <sabre@nondot.org>
Mon, 15 Oct 2007 17:16:12 +0000 (17:16 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 15 Oct 2007 17:16:12 +0000 (17:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42992 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp

index 31107d11bc632a1083623b6972bca306f87822eb..d815111048d5d8cbc8a2e53d5d9136835d5ca9f3 100644 (file)
@@ -161,8 +161,11 @@ private:
   SDOperand PromoteOperand_FP_ROUND(SDNode *N);
   SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo);
   SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo);
+  SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo);
   SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo);
   
+  void PromoteSetCCOperands(SDOperand &LHS,SDOperand &RHS, ISD::CondCode Code);
+
   // Operand Expansion.
   bool ExpandOperand(SDNode *N, unsigned OperandNo);
   SDOperand ExpandOperand_TRUNCATE(SDNode *N);
@@ -328,7 +331,7 @@ void DAGTypeLegalizer::MarkNewNodes(SDNode *N) {
   // Okay, we know that this node is new.  Recursively walk all of its operands
   // to see if they are new also.  The depth of this walk is bounded by the size
   // of the new tree that was constructed (usually 2-3 nodes), so we don't worry
-  // about revisitating of nodes.
+  // about revisiting of nodes.
   //
   // As we walk the operands, keep track of the number of nodes that are
   // processed.  If non-zero, this will become the new nodeid of this node.
@@ -1141,6 +1144,8 @@ bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) {
     
   case ISD::SELECT:      Res = PromoteOperand_SELECT(N, OpNo); break;
   case ISD::BRCOND:      Res = PromoteOperand_BRCOND(N, OpNo); break;
+  case ISD::BR_CC:       Res = PromoteOperand_BR_CC(N, OpNo); break;
+
   case ISD::STORE:       Res = PromoteOperand_STORE(cast<StoreSDNode>(N),
                                                     OpNo); break;
   }
@@ -1226,6 +1231,64 @@ SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) {
                                 N->getOperand(2));
 }
 
+SDOperand DAGTypeLegalizer::PromoteOperand_BR_CC(SDNode *N, unsigned OpNo) {
+  assert(OpNo == 2 && "Don't know how to promote this operand");
+  
+  SDOperand LHS = N->getOperand(2);
+  SDOperand RHS = N->getOperand(3);
+  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
+  
+  // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
+  // legal types.
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+                                N->getOperand(1), LHS, RHS, N->getOperand(4));
+}
+
+/// PromoteSetCCOperands - Promote the operands of a comparison.  This code is
+/// shared among BR_CC, SELECT_CC, and SETCC handlers.
+void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
+                                            ISD::CondCode CCCode) {
+  MVT::ValueType VT = NewLHS.getValueType();
+  
+  // Get the promoted values.
+  NewLHS = GetPromotedOp(NewLHS);
+  NewRHS = GetPromotedOp(NewRHS);
+  
+  // If this is an FP compare, the operands have already been extended.
+  if (!MVT::isInteger(NewLHS.getValueType()))
+    return;
+  
+  // Otherwise, we have to insert explicit sign or zero extends.  Note
+  // that we could insert sign extends for ALL conditions, but zero extend
+  // is cheaper on many machines (an AND instead of two shifts), so prefer
+  // it.
+  switch (CCCode) {
+  default: assert(0 && "Unknown integer comparison!");
+  case ISD::SETEQ:
+  case ISD::SETNE:
+  case ISD::SETUGE:
+  case ISD::SETUGT:
+  case ISD::SETULE:
+  case ISD::SETULT:
+    // ALL of these operations will work if we either sign or zero extend
+    // the operands (including the unsigned comparisons!).  Zero extend is
+    // usually a simpler/cheaper operation, so prefer it.
+    NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
+    NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
+    return;
+  case ISD::SETGE:
+  case ISD::SETGT:
+  case ISD::SETLT:
+  case ISD::SETLE:
+    NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS,
+                         DAG.getValueType(VT));
+    NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
+                         DAG.getValueType(VT));
+    return;
+  }
+}
+  
+
 SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){
   SDOperand Ch = N->getChain(), Ptr = N->getBasePtr();
   int SVOffset = N->getSrcValueOffset();
@@ -1316,7 +1379,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_SETCC(SDNode *N) {
                                 DAG.getCondCode(CCCode));
 }
 
-/// ExpandSetCCOperands - Expand the operands to a comparison.  This code is
+/// ExpandSetCCOperands - Expand the operands of a comparison.  This code is
 /// shared among BR_CC, SELECT_CC, and SETCC handlers.
 void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
                                            ISD::CondCode &CCCode) {