aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2009-04-29 05:20:52 +0000
committerNate Begeman <natebegeman@mac.com>2009-04-29 05:20:52 +0000
commit5a5ca1519e04310f585197c20e7ae584b7f2d11f (patch)
tree6483f04d2e9e63d4a4f2ade6113f882a78359039 /lib/CodeGen
parenta3518a1d6a6a9a7519d3a8d434cde51617c1dc22 (diff)
downloadexternal_llvm-5a5ca1519e04310f585197c20e7ae584b7f2d11f.zip
external_llvm-5a5ca1519e04310f585197c20e7ae584b7f2d11f.tar.gz
external_llvm-5a5ca1519e04310f585197c20e7ae584b7f2d11f.tar.bz2
Implement review feedback for vector shuffle work.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70372 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp20
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp39
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h5
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp28
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp58
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp51
6 files changed, 105 insertions, 96 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 8a41423..226699b 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -5163,13 +5163,14 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
}
LoadSDNode *LN0 = NULL;
+ const ShuffleVectorSDNode *SVN = NULL;
if (ISD::isNormalLoad(InVec.getNode())) {
LN0 = cast<LoadSDNode>(InVec);
} else if (InVec.getOpcode() == ISD::SCALAR_TO_VECTOR &&
InVec.getOperand(0).getValueType() == EVT &&
ISD::isNormalLoad(InVec.getOperand(0).getNode())) {
LN0 = cast<LoadSDNode>(InVec.getOperand(0));
- } else if (InVec.getOpcode() == ISD::VECTOR_SHUFFLE) {
+ } else if ((SVN = dyn_cast<ShuffleVectorSDNode>(InVec))) {
// (vextract (vector_shuffle (load $addr), v2, <1, u, u, u>), 1)
// =>
// (load $addr+1*size)
@@ -5178,14 +5179,17 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
// to examine the mask.
if (BCNumEltsChanged)
return SDValue();
- int Idx = cast<ShuffleVectorSDNode>(InVec)->getMaskElt(Elt);
- int NumElems = InVec.getValueType().getVectorNumElements();
- InVec = (Idx < NumElems) ? InVec.getOperand(0) : InVec.getOperand(1);
+
+ // Select the input vector, guarding against out of range extract vector.
+ unsigned NumElems = VT.getVectorNumElements();
+ int Idx = (Elt > NumElems) ? -1 : SVN->getMaskElt(Elt);
+ InVec = (Idx < (int)NumElems) ? InVec.getOperand(0) : InVec.getOperand(1);
+
if (InVec.getOpcode() == ISD::BIT_CONVERT)
InVec = InVec.getOperand(0);
if (ISD::isNormalLoad(InVec.getNode())) {
LN0 = cast<LoadSDNode>(InVec);
- Elt = (Idx < NumElems) ? Idx : Idx - NumElems;
+ Elt = (Idx < (int)NumElems) ? Idx : Idx - NumElems;
}
}
@@ -5280,7 +5284,11 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
SDValue Extract = N->getOperand(i);
SDValue ExtVal = Extract.getOperand(1);
if (Extract.getOperand(0) == VecIn1) {
- Mask.push_back(cast<ConstantSDNode>(ExtVal)->getZExtValue());
+ unsigned ExtIndex = cast<ConstantSDNode>(ExtVal)->getZExtValue();
+ if (ExtIndex > VT.getVectorNumElements())
+ return SDValue();
+
+ Mask.push_back(ExtIndex);
continue;
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 25305ea..f772f16 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -267,10 +267,13 @@ private:
bool isVolatile, SDValue ValOp,
unsigned StWidth, DebugLoc dl);
- /// promoteShuffle - Promote a shuffle mask of a vector VT to perform the
- /// same shuffle on a vector of NVT. Must not create an illegal shuffle mask.
- SDValue promoteShuffle(MVT NVT, MVT VT, DebugLoc dl, SDValue N1, SDValue N2,
- SmallVectorImpl<int> &Mask) const;
+ /// ShuffleWithNarrowerEltType - Return a vector shuffle operation which
+ /// performs the same shuffe in terms of order or result bytes, but on a type
+ /// whose vector element type is narrower than the original shuffle type.
+ /// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3>
+ SDValue ShuffleWithNarrowerEltType(MVT NVT, MVT VT, DebugLoc dl,
+ SDValue N1, SDValue N2,
+ SmallVectorImpl<int> &Mask) const;
bool LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest,
SmallPtrSet<SDNode*, 32> &NodesLeadingTo);
@@ -313,15 +316,17 @@ private:
};
}
-/// promoteShuffle - Promote a shuffle mask of a vector VT to perform the
-/// same shuffle on a vector of NVT. Must not create an illegal shuffle mask.
+/// ShuffleWithNarrowerEltType - Return a vector shuffle operation which
+/// performs the same shuffe in terms of order or result bytes, but on a type
+/// whose vector element type is narrower than the original shuffle type.
/// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3>
-SDValue SelectionDAGLegalize::promoteShuffle(MVT NVT, MVT VT, DebugLoc dl,
- SDValue N1, SDValue N2,
+SDValue
+SelectionDAGLegalize::ShuffleWithNarrowerEltType(MVT NVT, MVT VT, DebugLoc dl,
+ SDValue N1, SDValue N2,
SmallVectorImpl<int> &Mask) const {
MVT EltVT = NVT.getVectorElementType();
- int NumMaskElts = VT.getVectorNumElements();
- int NumDestElts = NVT.getVectorNumElements();
+ unsigned NumMaskElts = VT.getVectorNumElements();
+ unsigned NumDestElts = NVT.getVectorNumElements();
unsigned NumEltsGrowth = NumDestElts / NumMaskElts;
assert(NumEltsGrowth && "Cannot promote to vector type with fewer elts!");
@@ -330,7 +335,7 @@ SDValue SelectionDAGLegalize::promoteShuffle(MVT NVT, MVT VT, DebugLoc dl,
return DAG.getVectorShuffle(NVT, dl, N1, N2, &Mask[0]);
SmallVector<int, 8> NewMask;
- for (int i = 0; i != NumMaskElts; ++i) {
+ for (unsigned i = 0; i != NumMaskElts; ++i) {
int Idx = Mask[i];
for (unsigned j = 0; j != NumEltsGrowth; ++j) {
if (Idx < 0)
@@ -339,7 +344,7 @@ SDValue SelectionDAGLegalize::promoteShuffle(MVT NVT, MVT VT, DebugLoc dl,
NewMask.push_back(Idx * NumEltsGrowth + j);
}
}
- assert((int)NewMask.size() == NumDestElts && "Non-integer NumEltsGrowth?");
+ assert(NewMask.size() == NumDestElts && "Non-integer NumEltsGrowth?");
assert(TLI.isShuffleMaskLegal(NewMask, NVT) && "Shuffle not legal?");
return DAG.getVectorShuffle(NVT, dl, N1, N2, &NewMask[0]);
}
@@ -1678,7 +1683,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
MVT VT = Result.getValueType();
- // Copy the Mask to a local SmallVector for use wi
+ // Copy the Mask to a local SmallVector for use with isShuffleMaskLegal.
SmallVector<int, 8> Mask;
cast<ShuffleVectorSDNode>(Result)->getMask(Mask);
@@ -1698,14 +1703,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
// FALLTHROUGH
case TargetLowering::Expand: {
MVT EltVT = VT.getVectorElementType();
- int NumElems = VT.getVectorNumElements();
+ unsigned NumElems = VT.getVectorNumElements();
SmallVector<SDValue, 8> Ops;
- for (int i = 0; i != NumElems; ++i) {
+ for (unsigned i = 0; i != NumElems; ++i) {
if (Mask[i] < 0) {
Ops.push_back(DAG.getUNDEF(EltVT));
continue;
}
- int Idx = Mask[i];
+ unsigned Idx = Mask[i];
if (Idx < NumElems)
Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Tmp1,
DAG.getIntPtrConstant(Idx)));
@@ -1726,7 +1731,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp2);
// Convert the shuffle mask to the right # elements.
- Result = promoteShuffle(NVT, OVT, dl, Tmp1, Tmp2, Mask);
+ Result = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask);
Result = DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Result);
break;
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 330b5e7..382e270 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -559,7 +559,8 @@ private:
void SplitVecRes_LOAD(LoadSDNode *N, SDValue &Lo, SDValue &Hi);
void SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi);
void SplitVecRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi);
- void SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo, SDValue &Hi);
+ void SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N, SDValue &Lo,
+ SDValue &Hi);
void SplitVecRes_VSETCC(SDNode *N, SDValue &Lo, SDValue &Hi);
// Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>.
@@ -602,7 +603,7 @@ private:
SDValue WidenVecRes_SELECT(SDNode* N);
SDValue WidenVecRes_SELECT_CC(SDNode* N);
SDValue WidenVecRes_UNDEF(SDNode *N);
- SDValue WidenVecRes_VECTOR_SHUFFLE(SDNode *N);
+ SDValue WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N);
SDValue WidenVecRes_VSETCC(SDNode* N);
SDValue WidenVecRes_Binary(SDNode *N);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
index f35db83..68967cc 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
@@ -383,7 +383,8 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
case ISD::SCALAR_TO_VECTOR: SplitVecRes_SCALAR_TO_VECTOR(N, Lo, Hi); break;
case ISD::LOAD: SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi);break;
- case ISD::VECTOR_SHUFFLE: SplitVecRes_VECTOR_SHUFFLE(N, Lo, Hi); break;
+ case ISD::VECTOR_SHUFFLE:
+ SplitVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N), Lo, Hi); break;
case ISD::VSETCC: SplitVecRes_VSETCC(N, Lo, Hi); break;
case ISD::CTTZ:
@@ -757,11 +758,10 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi);
}
-void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo,
- SDValue &Hi) {
+void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N,
+ SDValue &Lo, SDValue &Hi) {
// The low and high parts of the original input give four input vectors.
SDValue Inputs[4];
- ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N);
DebugLoc dl = N->getDebugLoc();
GetSplitVector(N->getOperand(0), Inputs[0], Inputs[1]);
GetSplitVector(N->getOperand(1), Inputs[2], Inputs[3]);
@@ -786,7 +786,7 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo,
bool useBuildVector = false;
for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
// The mask element. This indexes into the input.
- int Idx = SVN->getMaskElt(FirstMaskIdx + MaskOffset);
+ int Idx = N->getMaskElt(FirstMaskIdx + MaskOffset);
// The input vector this mask element indexes into.
unsigned Input = (unsigned)Idx / NewElts;
@@ -831,7 +831,7 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo,
// Extract the input elements by hand.
for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
// The mask element. This indexes into the input.
- int Idx = SVN->getMaskElt(FirstMaskIdx + MaskOffset);
+ int Idx = N->getMaskElt(FirstMaskIdx + MaskOffset);
// The input vector this mask element indexes into.
unsigned Input = (unsigned)Idx / NewElts;
@@ -1102,7 +1102,8 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
case ISD::SELECT: Res = WidenVecRes_SELECT(N); break;
case ISD::SELECT_CC: Res = WidenVecRes_SELECT_CC(N); break;
case ISD::UNDEF: Res = WidenVecRes_UNDEF(N); break;
- case ISD::VECTOR_SHUFFLE: Res = WidenVecRes_VECTOR_SHUFFLE(N); break;
+ case ISD::VECTOR_SHUFFLE:
+ Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N)); break;
case ISD::VSETCC: Res = WidenVecRes_VSETCC(N); break;
case ISD::ADD:
@@ -1684,13 +1685,12 @@ SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) {
return DAG.getUNDEF(WidenVT);
}
-SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(SDNode *N) {
- ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N);
+SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N) {
MVT VT = N->getValueType(0);
- int NumElts = VT.getVectorNumElements();
DebugLoc dl = N->getDebugLoc();
MVT WidenVT = TLI.getTypeToTransformTo(VT);
+ unsigned NumElts = VT.getVectorNumElements();
unsigned WidenNumElts = WidenVT.getVectorNumElements();
SDValue InOp1 = GetWidenedVector(N->getOperand(0));
@@ -1698,14 +1698,14 @@ SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(SDNode *N) {
// Adjust mask based on new input vector length.
SmallVector<int, 16> NewMask;
- for (int i = 0; i < NumElts; ++i) {
- int Idx = SVN->getMaskElt(i);
- if (Idx < NumElts)
+ for (unsigned i = 0; i != NumElts; ++i) {
+ int Idx = N->getMaskElt(i);
+ if (Idx < (int)NumElts)
NewMask.push_back(Idx);
else
NewMask.push_back(Idx - NumElts + WidenNumElts);
}
- for (unsigned i = NumElts; i < WidenNumElts; ++i)
+ for (unsigned i = NumElts; i != WidenNumElts; ++i)
NewMask.push_back(-1);
return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, &NewMask[0]);
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 1c85e9d..d6a421d 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1133,6 +1133,9 @@ SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) {
return SDValue(CondCodeNodes[Cond], 0);
}
+// commuteShuffle - swaps the values of N1 and N2, and swaps all indices in
+// the shuffle mask M that point at N1 to point at N2, and indices that point
+// N2 to point at N1.
static void commuteShuffle(SDValue &N1, SDValue &N2, SmallVectorImpl<int> &M) {
std::swap(N1, N2);
int NElts = M.size();
@@ -1158,21 +1161,18 @@ SDValue SelectionDAG::getVectorShuffle(MVT VT, DebugLoc dl, SDValue N1,
// Validate that all indices in Mask are within the range of the elements
// input to the shuffle.
- int NElts = VT.getVectorNumElements();
+ unsigned NElts = VT.getVectorNumElements();
SmallVector<int, 8> MaskVec;
- for (int i = 0; i != NElts; ++i) {
- if (Mask[i] >= (NElts * 2)) {
- assert(0 && "Index out of range");
- return SDValue();
- }
+ for (unsigned i = 0; i != NElts; ++i) {
+ assert(Mask[i] < (int)(NElts * 2) && "Index out of range");
MaskVec.push_back(Mask[i]);
}
// Canonicalize shuffle v, v -> v, undef
if (N1 == N2) {
N2 = getUNDEF(VT);
- for (int i = 0; i != NElts; ++i)
- if (MaskVec[i] >= NElts) MaskVec[i] -= NElts;
+ for (unsigned i = 0; i != NElts; ++i)
+ if (MaskVec[i] >= (int)NElts) MaskVec[i] -= NElts;
}
// Canonicalize shuffle undef, v -> v, undef. Commute the shuffle mask.
@@ -1183,8 +1183,8 @@ SDValue SelectionDAG::getVectorShuffle(MVT VT, DebugLoc dl, SDValue N1,
// Canonicalize all index into rhs, -> shuffle rhs, undef
bool AllLHS = true, AllRHS = true;
bool N2Undef = N2.getOpcode() == ISD::UNDEF;
- for (int i = 0; i != NElts; ++i) {
- if (MaskVec[i] >= NElts) {
+ for (unsigned i = 0; i != NElts; ++i) {
+ if (MaskVec[i] >= (int)NElts) {
if (N2Undef)
MaskVec[i] = -1;
else
@@ -1195,7 +1195,7 @@ SDValue SelectionDAG::getVectorShuffle(MVT VT, DebugLoc dl, SDValue N1,
}
if (AllLHS && AllRHS)
return getUNDEF(VT);
- if (AllLHS)
+ if (AllLHS && !N2Undef)
N2 = getUNDEF(VT);
if (AllRHS) {
N1 = getUNDEF(VT);
@@ -1205,8 +1205,8 @@ SDValue SelectionDAG::getVectorShuffle(MVT VT, DebugLoc dl, SDValue N1,
// If Identity shuffle, or all shuffle in to undef, return that node.
bool AllUndef = true;
bool Identity = true;
- for (int i = 0; i < NElts; ++i) {
- if (MaskVec[i] >= 0 && MaskVec[i] != i) Identity = false;
+ for (unsigned i = 0; i != NElts; ++i) {
+ if (MaskVec[i] >= 0 && MaskVec[i] != (int)i) Identity = false;
if (MaskVec[i] >= 0) AllUndef = false;
}
if (Identity)
@@ -1217,7 +1217,7 @@ SDValue SelectionDAG::getVectorShuffle(MVT VT, DebugLoc dl, SDValue N1,
FoldingSetNodeID ID;
SDValue Ops[2] = { N1, N2 };
AddNodeIDNode(ID, ISD::VECTOR_SHUFFLE, getVTList(VT), Ops, 2);
- for (int i = 0; i != NElts; ++i)
+ for (unsigned i = 0; i != NElts; ++i)
ID.AddInteger(MaskVec[i]);
void* IP = 0;
@@ -2195,14 +2195,14 @@ bool SelectionDAG::isVerifiedDebugInfoDesc(SDValue Op) const {
/// getShuffleScalarElt - Returns the scalar element that will make up the ith
/// element of the result of the vector shuffle.
-SDValue SelectionDAG::getShuffleScalarElt(const SDNode *N, unsigned i) {
+SDValue SelectionDAG::getShuffleScalarElt(const ShuffleVectorSDNode *N,
+ unsigned i) {
MVT VT = N->getValueType(0);
DebugLoc dl = N->getDebugLoc();
- const ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(N);
- int Index = SVN->getMaskElt(i);
- if (Index < 0)
+ if (N->getMaskElt(i) < 0)
return getUNDEF(VT.getVectorElementType());
- int NumElems = VT.getVectorNumElements();
+ unsigned Index = N->getMaskElt(i);
+ unsigned NumElems = VT.getVectorNumElements();
SDValue V = (Index < NumElems) ? N->getOperand(0) : N->getOperand(1);
Index %= NumElems;
@@ -2217,8 +2217,8 @@ SDValue SelectionDAG::getShuffleScalarElt(const SDNode *N, unsigned i) {
: getUNDEF(VT.getVectorElementType());
if (V.getOpcode() == ISD::BUILD_VECTOR)
return V.getOperand(Index);
- if (V.getOpcode() == ISD::VECTOR_SHUFFLE)
- return getShuffleScalarElt(V.getNode(), Index);
+ if (const ShuffleVectorSDNode *SVN = dyn_cast<ShuffleVectorSDNode>(V))
+ return getShuffleScalarElt(SVN, Index);
return SDValue();
}
@@ -5726,11 +5726,19 @@ bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,
}
bool ShuffleVectorSDNode::isSplatMask(const int *Mask, MVT VT) {
- int Idx = -1;
- for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
- if (Idx < 0) Idx = Mask[i];
+ // Find the first non-undef value in the shuffle mask.
+ unsigned i, e;
+ for (i = 0, e = VT.getVectorNumElements(); i != e && Mask[i] < 0; ++i)
+ /* search */;
+
+ // If we hit the end of the mask looking for a non-undef value, return false.
+ if (i == e)
+ return false;
+
+ // Make sure all remaining elements are either undef or the same as the first
+ // non-undef value.
+ for (int Idx = Mask[i]; i != e; ++i)
if (Mask[i] >= 0 && Mask[i] != Idx)
return false;
- }
return true;
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index 6fe5657..afadd62 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -2431,10 +2431,10 @@ void SelectionDAGLowering::visitExtractElement(User &I) {
// Utility for visitShuffleVector - Returns true if the mask is mask starting
// from SIndx and increasing to the element length (undefs are allowed).
-static bool SequentialMask(SmallVectorImpl<int> &Mask, int SIndx) {
- int MaskNumElts = Mask.size();
- for (int i = 0; i != MaskNumElts; ++i)
- if ((Mask[i] >= 0) && (Mask[i] != i + SIndx))
+static bool SequentialMask(SmallVectorImpl<int> &Mask, unsigned SIndx) {
+ unsigned MaskNumElts = Mask.size();
+ for (unsigned i = 0; i != MaskNumElts; ++i)
+ if ((Mask[i] >= 0) && (Mask[i] != (int)(i + SIndx)))
return false;
return true;
}
@@ -2448,8 +2448,8 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
// representing undef values.
SmallVector<Constant*, 8> MaskElts;
cast<Constant>(I.getOperand(2))->getVectorElements(MaskElts);
- int MaskNumElts = MaskElts.size();
- for (int i = 0; i != MaskNumElts; ++i) {
+ unsigned MaskNumElts = MaskElts.size();
+ for (unsigned i = 0; i != MaskNumElts; ++i) {
if (isa<UndefValue>(MaskElts[i]))
Mask.push_back(-1);
else
@@ -2458,7 +2458,7 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
MVT VT = TLI.getValueType(I.getType());
MVT SrcVT = Src1.getValueType();
- int SrcNumElts = SrcVT.getVectorNumElements();
+ unsigned SrcNumElts = SrcVT.getVectorNumElements();
if (SrcNumElts == MaskNumElts) {
setValue(&I, DAG.getVectorShuffle(VT, getCurDebugLoc(), Src1, Src2,
@@ -2498,9 +2498,9 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
// Readjust mask for new input vector length.
SmallVector<int, 8> MappedOps;
- for (int i = 0; i != MaskNumElts; ++i) {
+ for (unsigned i = 0; i != MaskNumElts; ++i) {
int Idx = Mask[i];
- if (Idx < SrcNumElts)
+ if (Idx < (int)SrcNumElts)
MappedOps.push_back(Idx);
else
MappedOps.push_back(Idx + MaskNumElts - SrcNumElts);
@@ -2511,32 +2511,19 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
}
if (SrcNumElts > MaskNumElts) {
- // Resulting vector is shorter than the incoming vector.
- if (SrcNumElts == MaskNumElts && SequentialMask(Mask,0)) {
- // Shuffle extracts 1st vector.
- setValue(&I, Src1);
- return;
- }
-
- if (SrcNumElts == MaskNumElts && SequentialMask(Mask,MaskNumElts)) {
- // Shuffle extracts 2nd vector.
- setValue(&I, Src2);
- return;
- }
-
// Analyze the access pattern of the vector to see if we can extract
// two subvectors and do the shuffle. The analysis is done by calculating
// the range of elements the mask access on both vectors.
int MinRange[2] = { SrcNumElts+1, SrcNumElts+1};
int MaxRange[2] = {-1, -1};
- for (int i = 0; i != MaskNumElts; ++i) {
+ for (unsigned i = 0; i != MaskNumElts; ++i) {
int Idx = Mask[i];
int Input = 0;
if (Idx < 0)
continue;
- if (Idx >= SrcNumElts) {
+ if (Idx >= (int)SrcNumElts) {
Input = 1;
Idx -= SrcNumElts;
}
@@ -2551,18 +2538,18 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
int RangeUse[2] = { 2, 2 }; // 0 = Unused, 1 = Extract, 2 = Can not Extract.
int StartIdx[2]; // StartIdx to extract from
for (int Input=0; Input < 2; ++Input) {
- if (MinRange[Input] == SrcNumElts+1 && MaxRange[Input] == -1) {
+ if (MinRange[Input] == (int)(SrcNumElts+1) && MaxRange[Input] == -1) {
RangeUse[Input] = 0; // Unused
StartIdx[Input] = 0;
- } else if (MaxRange[Input] - MinRange[Input] < MaskNumElts) {
+ } else if (MaxRange[Input] - MinRange[Input] < (int)MaskNumElts) {
// Fits within range but we should see if we can find a good
// start index that is a multiple of the mask length.
- if (MaxRange[Input] < MaskNumElts) {
+ if (MaxRange[Input] < (int)MaskNumElts) {
RangeUse[Input] = 1; // Extract from beginning of the vector
StartIdx[Input] = 0;
} else {
StartIdx[Input] = (MinRange[Input]/MaskNumElts)*MaskNumElts;
- if (MaxRange[Input] - StartIdx[Input] < MaskNumElts &&
+ if (MaxRange[Input] - StartIdx[Input] < (int)MaskNumElts &&
StartIdx[Input] + MaskNumElts < SrcNumElts)
RangeUse[Input] = 1; // Extract from a multiple of the mask length.
}
@@ -2586,11 +2573,11 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
}
// Calculate new mask.
SmallVector<int, 8> MappedOps;
- for (int i = 0; i != MaskNumElts; ++i) {
+ for (unsigned i = 0; i != MaskNumElts; ++i) {
int Idx = Mask[i];
if (Idx < 0)
MappedOps.push_back(Idx);
- else if (Idx < SrcNumElts)
+ else if (Idx < (int)SrcNumElts)
MappedOps.push_back(Idx - StartIdx[0]);
else
MappedOps.push_back(Idx - SrcNumElts - StartIdx[1] + MaskNumElts);
@@ -2607,12 +2594,12 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
MVT EltVT = VT.getVectorElementType();
MVT PtrVT = TLI.getPointerTy();
SmallVector<SDValue,8> Ops;
- for (int i = 0; i != MaskNumElts; ++i) {
+ for (unsigned i = 0; i != MaskNumElts; ++i) {
if (Mask[i] < 0) {
Ops.push_back(DAG.getUNDEF(EltVT));
} else {
int Idx = Mask[i];
- if (Idx < SrcNumElts)
+ if (Idx < (int)SrcNumElts)
Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(),
EltVT, Src1, DAG.getConstant(Idx, PtrVT)));
else