Change RET node to include signness information of the return values. e.g.
authorEvan Cheng <evan.cheng@apple.com>
Fri, 26 May 2006 23:09:09 +0000 (23:09 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 26 May 2006 23:09:09 +0000 (23:09 +0000)
RET chain, value1, sign1, value2, sign2

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

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

index f21296afac309a73a7d6ba82701fc9b3646aaec9..0dcd8017995567d3afc7312ec79cb92961ff30a1 100644 (file)
@@ -414,8 +414,9 @@ namespace ISD {
     BR_CC,
     
     // RET - Return from function.  The first operand is the chain,
-    // and any subsequent operands are the return values for the
-    // function.  This operation can have variable number of operands.
+    // and any subsequent operands are pairs of return value and return value
+    // signness for the function.  This operation can have variable number of
+    // operands.
     RET,
 
     // INLINEASM - Represents an inline asm block.  This node always has two
index 979305fa41a70eb5a205849d63883853c840c3ca..e827bb63ff57cb70cce7476ecfbccd292b2e1181 100644 (file)
@@ -1453,17 +1453,18 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     LastCALLSEQ_END = DAG.getEntryNode();
       
     switch (Node->getNumOperands()) {
-    case 2:  // ret val
+    case 3:  // ret val
       Tmp2 = Node->getOperand(1);
+      Tmp3 = Node->getOperand(2);  // Signness
       switch (getTypeAction(Tmp2.getValueType())) {
       case Legal:
-        Result = DAG.UpdateNodeOperands(Result, Tmp1, LegalizeOp(Tmp2));
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, LegalizeOp(Tmp2), Tmp3);
         break;
       case Expand:
         if (Tmp2.getValueType() != MVT::Vector) {
           SDOperand Lo, Hi;
           ExpandOp(Tmp2, Lo, Hi);
-          Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Hi);
+          Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi, Tmp3);
         } else {
           SDNode *InVal = Tmp2.Val;
           unsigned NumElems =
@@ -1476,11 +1477,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
           if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) {
             // Turn this into a return of the packed type.
             Tmp2 = PackVectorOp(Tmp2, TVT);
-            Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+            Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
           } else if (NumElems == 1) {
             // Turn this into a return of the scalar type.
             Tmp2 = PackVectorOp(Tmp2, EVT);
-            Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+            Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
             
             // FIXME: Returns of gcc generic vectors smaller than a legal type
             // should be returned in integer registers!
@@ -1493,14 +1494,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
             // type should be returned by reference!
             SDOperand Lo, Hi;
             SplitVectorOp(Tmp2, Lo, Hi);
-            Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Hi);
+            Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi, Tmp3);
             Result = LegalizeOp(Result);
           }
         }
         break;
       case Promote:
         Tmp2 = PromoteOp(Node->getOperand(1));
-        Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
         Result = LegalizeOp(Result);
         break;
       }
@@ -1511,10 +1512,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     default: { // ret <values>
       std::vector<SDOperand> NewValues;
       NewValues.push_back(Tmp1);
-      for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i)
+      for (unsigned i = 1, e = Node->getNumOperands(); i < e; i += 2)
         switch (getTypeAction(Node->getOperand(i).getValueType())) {
         case Legal:
           NewValues.push_back(LegalizeOp(Node->getOperand(i)));
+          NewValues.push_back(Node->getOperand(i+1));
           break;
         case Expand: {
           SDOperand Lo, Hi;
@@ -1522,7 +1524,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
                  "FIXME: TODO: implement returning non-legal vector types!");
           ExpandOp(Node->getOperand(i), Lo, Hi);
           NewValues.push_back(Lo);
+          NewValues.push_back(Node->getOperand(i+1));
           NewValues.push_back(Hi);
+          NewValues.push_back(Node->getOperand(i+1));
           break;
         }
         case Promote:
index 9561d8a743bc78779c566136d6858c639d007dfd..b0af5441dd100f89265c1e6be4b79b703c4c2ba4 100644 (file)
@@ -722,10 +722,13 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
   NewValues.push_back(getRoot());
   for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
     SDOperand RetOp = getValue(I.getOperand(i));
+    bool isSigned = I.getOperand(i)->getType()->isSigned();
     
     // If this is an integer return value, we need to promote it ourselves to
     // the full width of a register, since LegalizeOp will use ANY_EXTEND rather
     // than sign/zero.
+    // FIXME: C calling convention requires the return type to be promoted to
+    // at least 32-bit. But this is not necessary for non-C calling conventions.
     if (MVT::isInteger(RetOp.getValueType()) && 
         RetOp.getValueType() < MVT::i64) {
       MVT::ValueType TmpVT;
@@ -734,12 +737,13 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
       else
         TmpVT = MVT::i32;
 
-      if (I.getOperand(i)->getType()->isSigned())
+      if (isSigned)
         RetOp = DAG.getNode(ISD::SIGN_EXTEND, TmpVT, RetOp);
       else
         RetOp = DAG.getNode(ISD::ZERO_EXTEND, TmpVT, RetOp);
     }
     NewValues.push_back(RetOp);
+    NewValues.push_back(DAG.getConstant(isSigned, MVT::i32));
   }
   DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, NewValues));
 }