diff options
author | Duncan Sands <baldrick@free.fr> | 2008-07-16 16:03:07 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-07-16 16:03:07 +0000 |
commit | 5d55dd1f8c8452d6c57563a545864f046867db33 (patch) | |
tree | a9901fb524c3286c1a31583f4e6afe4cd5d1cdd5 /lib/CodeGen | |
parent | 81391b579939dda6193b73c8f1d981147d7a6ab6 (diff) | |
download | external_llvm-5d55dd1f8c8452d6c57563a545864f046867db33.zip external_llvm-5d55dd1f8c8452d6c57563a545864f046867db33.tar.gz external_llvm-5d55dd1f8c8452d6c57563a545864f046867db33.tar.bz2 |
Add support for promoting and expanding AssertZext
and AssertSext. Needed when passing huge integer
parameters with the zeroext or signext attributes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53684 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 39 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.h | 3 |
2 files changed, 42 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 7a7288a..fa0a0fd 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -53,6 +53,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { #endif assert(0 && "Do not know how to promote this operator!"); abort(); + case ISD::AssertSext: Result = PromoteIntRes_AssertSext(N); break; + case ISD::AssertZext: Result = PromoteIntRes_AssertZext(N); break; case ISD::BIT_CONVERT: Result = PromoteIntRes_BIT_CONVERT(N); break; case ISD::BSWAP: Result = PromoteIntRes_BSWAP(N); break; case ISD::BUILD_PAIR: Result = PromoteIntRes_BUILD_PAIR(N); break; @@ -101,6 +103,23 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { SetPromotedInteger(SDOperand(N, ResNo), Result); } +SDOperand DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) { + // Sign-extend the new bits, and continue the assertion. + MVT OldVT = N->getValueType(0); + SDOperand Op = GetPromotedInteger(N->getOperand(0)); + return DAG.getNode(ISD::AssertSext, Op.getValueType(), + DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), Op, + DAG.getValueType(OldVT)), N->getOperand(1)); +} + +SDOperand DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) { + // Zero the new bits, and continue the assertion. + MVT OldVT = N->getValueType(0); + SDOperand Op = GetPromotedInteger(N->getOperand(0)); + return DAG.getNode(ISD::AssertZext, Op.getValueType(), + DAG.getZeroExtendInReg(Op, OldVT), N->getOperand(1)); +} + SDOperand DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { SDOperand InOp = N->getOperand(0); MVT InVT = InOp.getValueType(); @@ -827,6 +846,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; case ISD::ANY_EXTEND: ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break; + case ISD::AssertSext: ExpandIntRes_AssertSext(N, Lo, Hi); break; case ISD::AssertZext: ExpandIntRes_AssertZext(N, Lo, Hi); break; case ISD::BSWAP: ExpandIntRes_BSWAP(N, Lo, Hi); break; case ISD::Constant: ExpandIntRes_Constant(N, Lo, Hi); break; @@ -1115,6 +1135,25 @@ void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N, } } +void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + GetExpandedInteger(N->getOperand(0), Lo, Hi); + MVT NVT = Lo.getValueType(); + MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT(); + unsigned NVTBits = NVT.getSizeInBits(); + unsigned EVTBits = EVT.getSizeInBits(); + + if (NVTBits < EVTBits) { + Hi = DAG.getNode(ISD::AssertSext, NVT, Hi, + DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits))); + } else { + Lo = DAG.getNode(ISD::AssertSext, NVT, Lo, DAG.getValueType(EVT)); + // The high part replicates the sign bit of Lo, make it explicit. + Hi = DAG.getNode(ISD::SRA, NVT, Lo, + DAG.getConstant(NVTBits-1, TLI.getShiftAmountTy())); + } +} + void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N, SDOperand &Lo, SDOperand &Hi) { GetExpandedInteger(N->getOperand(0), Lo, Hi); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 3eaaaee..1959df5 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -212,6 +212,8 @@ private: // Integer Result Promotion. void PromoteIntegerResult(SDNode *N, unsigned ResNo); + SDOperand PromoteIntRes_AssertSext(SDNode *N); + SDOperand PromoteIntRes_AssertZext(SDNode *N); SDOperand PromoteIntRes_BIT_CONVERT(SDNode *N); SDOperand PromoteIntRes_BSWAP(SDNode *N); SDOperand PromoteIntRes_BUILD_PAIR(SDNode *N); @@ -269,6 +271,7 @@ private: // Integer Result Expansion. void ExpandIntegerResult(SDNode *N, unsigned ResNo); void ExpandIntRes_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandIntRes_AssertSext (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_AssertZext (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_Constant (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_CTLZ (SDNode *N, SDOperand &Lo, SDOperand &Hi); |