summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorGeoff Berry <gberry@codeaurora.org>2016-11-11 19:25:20 +0000
committerGeoff Berry <gberry@codeaurora.org>2016-11-11 19:25:20 +0000
commit25fa4999ff8c569912070019ee5d527d96f871d2 (patch)
tree2775f57f545b16e41a34a597a2a16694f3e368bb /llvm/lib
parentec80354873dab4a4b0263724f357b022bc19880a (diff)
downloadbcm5719-llvm-25fa4999ff8c569912070019ee5d527d96f871d2.tar.gz
bcm5719-llvm-25fa4999ff8c569912070019ee5d527d96f871d2.zip
[AArch64] Fix bugs in isel lowering replaceSplatVectorStore.
Summary: Fix off-by-one indexing error in loop checking that inserted value was a splat vector. Add code to check that INSERT_VECTOR_ELT nodes constructing the splat vector have the expected constant index values. Reviewers: t.p.northover, jmolloy, mcrosier Subscribers: aemerson, llvm-commits, rengolin Differential Revision: https://reviews.llvm.org/D26409 llvm-svn: 286616
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp38
1 files changed, 27 insertions, 11 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index d8ba19ac742..f0b6a270961 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -8783,26 +8783,42 @@ static SDValue replaceSplatVectorStore(SelectionDAG &DAG, StoreSDNode *St) {
if (VT.isFloatingPoint())
return SDValue();
- // Check for insert vector elements.
- if (StVal.getOpcode() != ISD::INSERT_VECTOR_ELT)
- return SDValue();
-
// We can express a splat as store pair(s) for 2 or 4 elements.
unsigned NumVecElts = VT.getVectorNumElements();
if (NumVecElts != 4 && NumVecElts != 2)
return SDValue();
- SDValue SplatVal = StVal.getOperand(1);
- unsigned RemainInsertElts = NumVecElts - 1;
// Check that this is a splat.
- while (--RemainInsertElts) {
- SDValue NextInsertElt = StVal.getOperand(0);
- if (NextInsertElt.getOpcode() != ISD::INSERT_VECTOR_ELT)
+ // Make sure that each of the relevant vector element locations are inserted
+ // to, i.e. 0 and 1 for v2i64 and 0, 1, 2, 3 for v4i32.
+ std::bitset<4> IndexNotInserted((1 << NumVecElts) - 1);
+ SDValue SplatVal;
+ for (unsigned I = 0; I < NumVecElts; ++I) {
+ // Check for insert vector elements.
+ if (StVal.getOpcode() != ISD::INSERT_VECTOR_ELT)
return SDValue();
- if (NextInsertElt.getOperand(1) != SplatVal)
+
+ // Check that same value is inserted at each vector element.
+ if (I == 0)
+ SplatVal = StVal.getOperand(1);
+ else if (StVal.getOperand(1) != SplatVal)
+ return SDValue();
+
+ // Check insert element index.
+ ConstantSDNode *CIndex = dyn_cast<ConstantSDNode>(StVal.getOperand(2));
+ if (!CIndex)
return SDValue();
- StVal = NextInsertElt;
+ uint64_t IndexVal = CIndex->getZExtValue();
+ if (IndexVal >= NumVecElts)
+ return SDValue();
+ IndexNotInserted.reset(IndexVal);
+
+ StVal = StVal.getOperand(0);
}
+ // Check that all vector element locations were inserted to.
+ if (IndexNotInserted.any())
+ return SDValue();
+
unsigned OrigAlignment = St->getAlignment();
unsigned EltOffset = NumVecElts == 4 ? 4 : 8;
unsigned Alignment = std::min(OrigAlignment, EltOffset);
OpenPOWER on IntegriCloud