diff options
author | Alexey Bataev <a.bataev@outlook.com> | 2023-09-20 09:25:20 -0700 |
---|---|---|
committer | Alexey Bataev <a.bataev@outlook.com> | 2023-09-20 09:54:15 -0700 |
commit | ebed4692f8160e65c5a04c3edfb61b82ca037574 (patch) | |
tree | 47b11751d5dc3cd6fecd69f00fea8ef27dca4287 /llvm/lib | |
parent | a590ff589c8dfe24560865dbb787bbfe2717ae88 (diff) | |
download | llvm-ebed4692f8160e65c5a04c3edfb61b82ca037574.zip llvm-ebed4692f8160e65c5a04c3edfb61b82ca037574.tar.gz llvm-ebed4692f8160e65c5a04c3edfb61b82ca037574.tar.bz2 |
[SLP]Fix a crash when trying to find operand with re-vectorized main
instruction.
Need to check if the operand scalars are vectorized in the a different
vector node, if the main instruction is already gets vectorized in other
vector node.
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 38ef4fa9..db0df8c 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -2916,8 +2916,11 @@ private: const TreeEntry *TE = getTreeEntry(V); assert((!TE || TE == Last || doesNotNeedToBeScheduled(V)) && "Scalar already in tree!"); - if (TE) + if (TE) { + if (TE != Last) + MultiNodeScalars.insert(V); continue; + } ScalarToTreeEntry[V] = Last; } // Update the scheduler bundle to point to this TreeEntry. @@ -2976,6 +2979,9 @@ private: /// Maps a specific scalar to its tree entry. SmallDenseMap<Value *, TreeEntry *> ScalarToTreeEntry; + /// List of scalars, used in several vectorize nodes. + SmallDenseSet<Value *> MultiNodeScalars; + /// Maps a value to the proposed vectorizable size. SmallDenseMap<Value *, unsigned> InstrElementSize; @@ -9843,17 +9849,32 @@ Value *BoUpSLP::vectorizeOperand(TreeEntry *E, unsigned NodeIdx) { S = getSameOpcode(*It, *TLI); } if (S.getOpcode()) { - if (TreeEntry *VE = getTreeEntry(S.OpValue); - VE && VE->isSame(VL) && - (any_of(VE->UserTreeIndices, - [E, NodeIdx](const EdgeInfo &EI) { - return EI.UserTE == E && EI.EdgeIdx == NodeIdx; - }) || - any_of(VectorizableTree, - [E, NodeIdx, VE](const std::unique_ptr<TreeEntry> &TE) { - return TE->isOperandGatherNode({E, NodeIdx}) && - VE->isSame(TE->Scalars); - }))) { + auto CheckSameVE = [&](const TreeEntry *VE) { + return VE->isSame(VL) && + (any_of(VE->UserTreeIndices, + [E, NodeIdx](const EdgeInfo &EI) { + return EI.UserTE == E && EI.EdgeIdx == NodeIdx; + }) || + any_of(VectorizableTree, + [E, NodeIdx, VE](const std::unique_ptr<TreeEntry> &TE) { + return TE->isOperandGatherNode({E, NodeIdx}) && + VE->isSame(TE->Scalars); + })); + }; + TreeEntry *VE = getTreeEntry(S.OpValue); + bool IsSameVE = VE && CheckSameVE(VE); + if (!IsSameVE && MultiNodeScalars.contains(S.OpValue)) { + auto *I = + find_if(VectorizableTree, [&](const std::unique_ptr<TreeEntry> &TE) { + return TE->State != TreeEntry::NeedToGather && TE.get() != VE && + CheckSameVE(TE.get()); + }); + if (I != VectorizableTree.end()) { + VE = I->get(); + IsSameVE = true; + } + } + if (IsSameVE) { auto FinalShuffle = [&](Value *V, ArrayRef<int> Mask) { ShuffleInstructionBuilder ShuffleBuilder(Builder, *this); ShuffleBuilder.add(V, Mask); |