diff options
| author | Geoff Berry <gberry@codeaurora.org> | 2016-11-11 19:25:20 +0000 |
|---|---|---|
| committer | Geoff Berry <gberry@codeaurora.org> | 2016-11-11 19:25:20 +0000 |
| commit | 25fa4999ff8c569912070019ee5d527d96f871d2 (patch) | |
| tree | 2775f57f545b16e41a34a597a2a16694f3e368bb /llvm/lib | |
| parent | ec80354873dab4a4b0263724f357b022bc19880a (diff) | |
| download | bcm5719-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.cpp | 38 |
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); |

