From 8e7d056bc5c0688501f6721994c8f4074d699c69 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 26 May 2006 23:09:09 +0000 Subject: Change RET node to include signness information of the return values. e.g. RET chain, value1, sign1, value2, sign2 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28509 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 20 ++++++++++++-------- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 6 +++++- 2 files changed, 17 insertions(+), 9 deletions(-) (limited to 'lib/CodeGen') diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 979305f..e827bb6 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -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 std::vector 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: diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 9561d8a..b0af544 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -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)); } -- cgit v1.1