diff options
author | Bob Wilson <bob.wilson@apple.com> | 2009-04-13 22:05:19 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2009-04-13 22:05:19 +0000 |
commit | b1303d05a89972195de023fda432cc621375a27c (patch) | |
tree | 83ded3f76bc8714c5a7be5b15d6abbd0fa45abcd /lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | |
parent | 88c7af096b09ad26cbcebfdf40151e04094b7460 (diff) |
Change SelectionDAG type legalization to allow BUILD_VECTOR operands to be
promoted to legal types without changing the type of the vector. This is
following a suggestion from Duncan
(http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-February/019923.html).
The transformation that used to be done during type legalization is now
postponed to DAG legalization. This allows the BUILD_VECTORs to be optimized
and potentially handled specially by target-specific code.
It turns out that this is also consistent with an optimization done by the
DAG combiner: a BUILD_VECTOR and INSERT_VECTOR_ELT may be combined by
replacing one of the BUILD_VECTOR operands with the newly inserted element;
but INSERT_VECTOR_ELT allows its scalar operand to be larger than the
element type, with any extra high bits being implicitly truncated. The
result is a BUILD_VECTOR where one of the operands has a type larger the
the vector element type.
Any code that operates on BUILD_VECTORs may now need to be aware of the
potential type discrepancy between the vector element type and the
BUILD_VECTOR operands. This patch updates all of the places that I could
find to handle that case.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68996 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 32 |
1 files changed, 10 insertions, 22 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 66a57dc432..115c9f8924 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -799,32 +799,20 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) { MVT VecVT = N->getValueType(0); unsigned NumElts = VecVT.getVectorNumElements(); assert(!(NumElts & 1) && "Legal vector of one illegal element?"); - DebugLoc dl = N->getDebugLoc(); - - // Build a vector of half the length out of elements of twice the bitwidth. - // For example <4 x i16> -> <2 x i32>. - MVT OldVT = N->getOperand(0).getValueType(); - MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits()); - assert(OldVT.isSimple() && NewVT.isSimple()); - std::vector<SDValue> NewElts; - NewElts.reserve(NumElts/2); + // Promote the inserted value. The type does not need to match the + // vector element type. Check that any extra bits introduced will be + // truncated away. + assert(N->getOperand(0).getValueType().getSizeInBits() >= + N->getValueType(0).getVectorElementType().getSizeInBits() && + "Type of inserted value narrower than vector element type!"); - for (unsigned i = 0; i < NumElts; i += 2) { - // Combine two successive elements into one promoted element. - SDValue Lo = N->getOperand(i); - SDValue Hi = N->getOperand(i+1); - if (TLI.isBigEndian()) - std::swap(Lo, Hi); - NewElts.push_back(JoinIntegers(Lo, Hi)); + SmallVector<SDValue, 16> NewOps; + for (unsigned i = 0; i < NumElts; ++i) { + NewOps.push_back(GetPromotedInteger(N->getOperand(i))); } - SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, - MVT::getVectorVT(NewVT, NewElts.size()), - &NewElts[0], NewElts.size()); - - // Convert the new vector to the old vector type. - return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec); + return DAG.UpdateNodeOperands(SDValue(N, 0), &NewOps[0], NumElts); } SDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) { |