summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-07-09 22:01:03 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-07-09 22:01:03 +0000
commitc680ac90032bf455b2bba77de538fccea08eb267 (patch)
tree00f8af7d1bfa6165c868a13adc39b98f4f7dd522 /lib/CodeGen
parent6dded67b0d6262964e22163d0ab37c9ee6957c0a (diff)
downloadexternal_llvm-c680ac90032bf455b2bba77de538fccea08eb267.zip
external_llvm-c680ac90032bf455b2bba77de538fccea08eb267.tar.gz
external_llvm-c680ac90032bf455b2bba77de538fccea08eb267.tar.bz2
Make EXTRACT_VECTOR_ELT a bit more flexible in terms of the returned
value. Adjust other code to deal with that correctly. Make DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT take advantage of this new flexibility to simplify the code and make it deal with unusual vectors (like <4 x i1>) correctly. Fixes PR3037. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75176 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp6
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp48
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp12
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp13
4 files changed, 24 insertions, 55 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index e31ea85..1945641 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1526,7 +1526,11 @@ SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) {
StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr);
- return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0);
+ if (Op.getValueType().isVector())
+ return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0);
+ else
+ return DAG.getExtLoad(ISD::EXTLOAD, dl, Op.getValueType(), Ch, StackPtr,
+ NULL, 0, Vec.getValueType().getVectorElementType());
}
SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) {
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index e6c8b48..958f72d 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -303,52 +303,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
}
SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
- MVT OldVT = N->getValueType(0);
- SDValue OldVec = N->getOperand(0);
- if (getTypeAction(OldVec.getValueType()) == WidenVector)
- OldVec = GetWidenedVector(N->getOperand(0));
- unsigned OldElts = OldVec.getValueType().getVectorNumElements();
DebugLoc dl = N->getDebugLoc();
-
- if (OldElts == 1) {
- assert(!isTypeLegal(OldVec.getValueType()) &&
- "Legal one-element vector of a type needing promotion!");
- // It is tempting to follow GetScalarizedVector by a call to
- // GetPromotedInteger, but this would be wrong because the
- // scalarized value may not yet have been processed.
- return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT),
- GetScalarizedVector(OldVec));
- }
-
- // Convert to a vector half as long with an element type of twice the width,
- // for example <4 x i16> -> <2 x i32>.
- assert(!(OldElts & 1) && "Odd length vectors not supported!");
- MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
- assert(OldVT.isSimple() && NewVT.isSimple());
-
- SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl,
- MVT::getVectorVT(NewVT, OldElts / 2),
- OldVec);
-
- // Extract the element at OldIdx / 2 from the new vector.
- SDValue OldIdx = N->getOperand(1);
- SDValue NewIdx = DAG.getNode(ISD::SRL, dl, OldIdx.getValueType(), OldIdx,
- DAG.getConstant(1, TLI.getPointerTy()));
- SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, NewIdx);
-
- // Select the appropriate half of the element: Lo if OldIdx was even,
- // Hi if it was odd.
- SDValue Lo = Elt;
- SDValue Hi = DAG.getNode(ISD::SRL, dl, NewVT, Elt,
- DAG.getConstant(OldVT.getSizeInBits(),
- TLI.getPointerTy()));
- if (TLI.isBigEndian())
- std::swap(Lo, Hi);
-
- // Extend to the promoted type.
- SDValue Odd = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, OldIdx);
- SDValue Res = DAG.getNode(ISD::SELECT, dl, NewVT, Odd, Hi, Lo);
- return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT), Res);
+ MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NVT, N->getOperand(0),
+ N->getOperand(1));
}
SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index 652c803..0b64446 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -331,7 +331,11 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) {
/// be scalarized, it must be <1 x ty>, so just return the element, ignoring the
/// index.
SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
- return GetScalarizedVector(N->getOperand(0));
+ SDValue Res = GetScalarizedVector(N->getOperand(0));
+ if (Res.getValueType() != N->getValueType(0))
+ Res = DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0),
+ Res);
+ return Res;
}
/// ScalarizeVecOp_STORE - If the value to store is a vector that needs to be
@@ -1052,7 +1056,8 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
// Load back the required element.
StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
- return DAG.getLoad(EltVT, dl, Store, StackPtr, SV, 0);
+ return DAG.getExtLoad(ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr,
+ SV, 0, EltVT);
}
SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
@@ -1904,9 +1909,8 @@ SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) {
SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
SDValue InOp = GetWidenedVector(N->getOperand(0));
- MVT EltVT = InOp.getValueType().getVectorElementType();
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(),
- EltVT, InOp, N->getOperand(1));
+ N->getValueType(0), InOp, N->getOperand(1));
}
SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 2d15494..29f0cb2 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2693,13 +2693,16 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
// expanding large vector constants.
if (N2C && N1.getOpcode() == ISD::BUILD_VECTOR) {
SDValue Elt = N1.getOperand(N2C->getZExtValue());
- if (Elt.getValueType() != VT) {
+ MVT VEltTy = N1.getValueType().getVectorElementType();
+ if (Elt.getValueType() != VEltTy) {
// If the vector element type is not legal, the BUILD_VECTOR operands
// are promoted and implicitly truncated. Make that explicit here.
- assert(VT.isInteger() && Elt.getValueType().isInteger() &&
- VT.bitsLE(Elt.getValueType()) &&
- "Bad type for BUILD_VECTOR operand");
- Elt = getNode(ISD::TRUNCATE, DL, VT, Elt);
+ Elt = getNode(ISD::TRUNCATE, DL, VEltTy, Elt);
+ }
+ if (VT != VEltTy) {
+ // If the vector element type is not legal, the EXTRACT_VECTOR_ELT
+ // result is implicitly extended.
+ Elt = getNode(ISD::ANY_EXTEND, DL, VT, Elt);
}
return Elt;
}