aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@outlook.com>2023-09-20 09:25:20 -0700
committerAlexey Bataev <a.bataev@outlook.com>2023-09-20 09:54:15 -0700
commitebed4692f8160e65c5a04c3edfb61b82ca037574 (patch)
tree47b11751d5dc3cd6fecd69f00fea8ef27dca4287 /llvm/lib
parenta590ff589c8dfe24560865dbb787bbfe2717ae88 (diff)
downloadllvm-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.cpp45
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);