summaryrefslogtreecommitdiff
path: root/gnu/llvm/lib/CodeGen/InterleavedAccessPass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lib/CodeGen/InterleavedAccessPass.cpp')
-rw-r--r--gnu/llvm/lib/CodeGen/InterleavedAccessPass.cpp8
1 files changed, 6 insertions, 2 deletions
diff --git a/gnu/llvm/lib/CodeGen/InterleavedAccessPass.cpp b/gnu/llvm/lib/CodeGen/InterleavedAccessPass.cpp
index c8f79d7fb71..ec35b3f6449 100644
--- a/gnu/llvm/lib/CodeGen/InterleavedAccessPass.cpp
+++ b/gnu/llvm/lib/CodeGen/InterleavedAccessPass.cpp
@@ -174,7 +174,7 @@ static bool isDeInterleaveMask(ArrayRef<int> Mask, unsigned &Factor,
/// I.e. <0, LaneLen, ... , LaneLen*(Factor - 1), 1, LaneLen + 1, ...>
/// E.g. For a Factor of 2 (LaneLen=4): <0, 4, 1, 5, 2, 6, 3, 7>
static bool isReInterleaveMask(ArrayRef<int> Mask, unsigned &Factor,
- unsigned MaxFactor) {
+ unsigned MaxFactor, unsigned OpNumElts) {
unsigned NumElts = Mask.size();
if (NumElts < 4)
return false;
@@ -246,6 +246,9 @@ static bool isReInterleaveMask(ArrayRef<int> Mask, unsigned &Factor,
if (StartMask < 0)
break;
+ // We must stay within the vectors; This case can happen with undefs.
+ if (StartMask + LaneLen > OpNumElts*2)
+ break;
}
// Found an interleaved mask of current factor.
@@ -406,7 +409,8 @@ bool InterleavedAccess::lowerInterleavedStore(
// Check if the shufflevector is RE-interleave shuffle.
unsigned Factor;
- if (!isReInterleaveMask(SVI->getShuffleMask(), Factor, MaxFactor))
+ unsigned OpNumElts = SVI->getOperand(0)->getType()->getVectorNumElements();
+ if (!isReInterleaveMask(SVI->getShuffleMask(), Factor, MaxFactor, OpNumElts))
return false;
DEBUG(dbgs() << "IA: Found an interleaved store: " << *SI << "\n");