From d22ec5f62813f8cf2ed8091f44a14377209b1a59 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Wed, 29 Oct 2008 14:22:20 +0000 Subject: [PATCH] Add sanity checking for BUILD_PAIR (I noticed the other day that PPC custom lowering could create a BUILD_PAIR of two f64 with a result type of... f64! - already fixed). Fix a place that triggers the sanity check. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58378 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/ValueTypes.h | 18 +++++++++++++++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 22 +++++++++++++++---- .../SelectionDAG/SelectionDAGBuild.cpp | 9 +++++--- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index f1b489ee3b3..c4bcaf174a9 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -142,6 +142,24 @@ namespace llvm { inline bool operator== (const MVT VT) const { return V == VT.V; } inline bool operator!= (const MVT VT) const { return V != VT.V; } + /// getFloatingPointVT - Returns the MVT that represents a floating point + /// type with the given number of bits. There are two floating point types + /// with 128 bits - this returns f128 rather than ppcf128. + static inline MVT getFloatingPointVT(unsigned BitWidth) { + switch (BitWidth) { + default: + assert(false && "Bad bit width!"); + case 32: + return f32; + case 64: + return f64; + case 80: + return f80; + case 128: + return f128; + } + } + /// getIntegerVT - Returns the MVT that represents an integer with the given /// number of bits. static inline MVT getIntegerVT(unsigned BitWidth) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 3d809b4983d..0c737261aa6 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -758,11 +758,25 @@ void SelectionDAG::VerifyNode(SDNode *N) { switch (N->getOpcode()) { default: break; + case ISD::BUILD_PAIR: { + MVT VT = N->getValueType(0); + assert(N->getNumValues() == 1 && "Too many results!"); + assert(!VT.isVector() && (VT.isInteger() || VT.isFloatingPoint()) && + "Wrong return type!"); + assert(N->getNumOperands() == 2 && "Wrong number of operands!"); + assert(N->getOperand(0).getValueType() == N->getOperand(1).getValueType() && + "Mismatched operand types!"); + assert(N->getOperand(0).getValueType().isInteger() == VT.isInteger() && + "Wrong operand type!"); + assert(VT.getSizeInBits() == 2 * N->getOperand(0).getValueSizeInBits() && + "Wrong return type size"); + break; + } case ISD::BUILD_VECTOR: { - assert(N->getNumValues() == 1 && "Too many results for BUILD_VECTOR!"); - assert(N->getValueType(0).isVector() && "Wrong BUILD_VECTOR return type!"); + assert(N->getNumValues() == 1 && "Too many results!"); + assert(N->getValueType(0).isVector() && "Wrong return type!"); assert(N->getNumOperands() == N->getValueType(0).getVectorNumElements() && - "Wrong number of BUILD_VECTOR operands!"); + "Wrong number of operands!"); // FIXME: Change vector_shuffle to a variadic node with mask elements being // operands of the node. Currently the mask is a BUILD_VECTOR passed as an // operand, and it is not always possible to legalize it. Turning off the @@ -770,7 +784,7 @@ void SelectionDAG::VerifyNode(SDNode *N) { // MVT EltVT = N->getValueType(0).getVectorElementType(); // for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) // assert(I->getSDValue().getValueType() == EltVT && -// "Wrong BUILD_VECTOR operand type!"); +// "Wrong operand type!"); break; } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index d04daeb76b5..e34e78fca6d 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -390,14 +390,17 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, ValueVT : MVT::getIntegerVT(RoundBits); SDValue Lo, Hi; + MVT HalfVT = ValueVT.isInteger() ? + MVT::getIntegerVT(RoundBits/2) : + MVT::getFloatingPointVT(RoundBits/2); + if (RoundParts > 2) { - MVT HalfVT = MVT::getIntegerVT(RoundBits/2); Lo = getCopyFromParts(DAG, Parts, RoundParts/2, PartVT, HalfVT); Hi = getCopyFromParts(DAG, Parts+RoundParts/2, RoundParts/2, PartVT, HalfVT); } else { - Lo = Parts[0]; - Hi = Parts[1]; + Lo = DAG.getNode(ISD::BIT_CONVERT, HalfVT, Parts[0]); + Hi = DAG.getNode(ISD::BIT_CONVERT, HalfVT, Parts[1]); } if (TLI.isBigEndian()) std::swap(Lo, Hi);