diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -7001,6 +7001,17 @@ const TreeEntry *E2 = P2.get(); if (E->Scalars.size() == E2->Scalars.size()) CommonVF = VF = E->Scalars.size(); + } else { + // P2 is empty, check that we have same node + reshuffle (if any). + if (E->Scalars.size() == Mask.size() && VF != Mask.size()) { + VF = E->Scalars.size(); + SmallVector CommonMask(Mask.begin(), Mask.end()); + ::addMask(CommonMask, E->getCommonMask()); + V1 = Constant::getNullValue( + FixedVectorType::get(E->Scalars.front()->getType(), VF)); + return BaseShuffleAnalysis::createShuffle( + V1, nullptr, CommonMask, Builder); + } } V1 = Constant::getNullValue( FixedVectorType::get(E->Scalars.front()->getType(), VF)); @@ -7281,7 +7292,17 @@ dbgs() << "SLP: perfect diamond match for gather bundle that starts with " << *VL.front() << ".\n"); - return 0; + // Restore the mask for previous partially matched values. + for (auto [I, V] : enumerate(E->Scalars)) { + if (isa(V)) { + Mask[I] = PoisonMaskElem; + continue; + } + if (Mask[I] == PoisonMaskElem) + Mask[I] = Entries.front()->findLaneForValue(V); + } + Estimator.add(Entries.front(), Mask); + return Estimator.finalize(E->ReuseShuffleIndices); } if (!Resized) { unsigned VF1 = Entries.front()->getVectorFactor(); diff --git a/llvm/test/Transforms/SLPVectorizer/X86/crash_clear_undefs.ll b/llvm/test/Transforms/SLPVectorizer/X86/crash_clear_undefs.ll --- a/llvm/test/Transforms/SLPVectorizer/X86/crash_clear_undefs.ll +++ b/llvm/test/Transforms/SLPVectorizer/X86/crash_clear_undefs.ll @@ -9,7 +9,7 @@ ; YAML-NEXT: Function: foo ; YAML-NEXT: Args: ; YAML-NEXT: - String: 'SLP vectorized with cost ' -; YAML-NEXT: - Cost: '-6' +; YAML-NEXT: - Cost: '-5' ; YAML-NEXT: - String: ' and with tree size ' ; YAML-NEXT: - TreeSize: '10' ; YAML-NEXT: ...