Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: BoUpSLP::isGatherShuffledSingleRegisterEntry
Issue title: [SLPVectorizer] Assertion `I1 == PoisonMaskElem && "Expected unused subvectors mask"' failed.
Labels: llvm:SLPVectorizer
crash-on-valid
Reported by: dtcxzyw

Reproducer: https://godbolt.org/z/3dahr6Mb4
```
; bin/opt -passes=slp-vectorizer reduced.ll -S
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i32 @main() {
entry:
  br label %func_135.exit.i

func_135.exit.i:
  %g_228.promoted166.i1105.i = phi i32 [ 0, %entry ]
  %cmp55.i.i1199.i = icmp ugt i32 %g_228.promoted166.i1105.i, 0
  %cmp55.1.i.i1200.i = icmp ugt i32 %g_228.promoted166.i1105.i, 0
  %cmp55.2.i.i1201.i = icmp ugt i32 %g_228.promoted166.i1105.i, 0
  %cmp55.3.i.i1202.i = icmp ugt i32 %g_228.promoted166.i1105.i, 0
  %0 = xor i1 %cmp55.2.i.i1201.i, %cmp55.3.i.i1202.i
  %1 = xor i1 %cmp55.1.i.i1200.i, %0
  %2 = xor i1 %cmp55.i.i1199.i, %1
  %dec.i.i1204.i = add i32 %g_228.promoted166.i1105.i, 0
  %cmp55.i.i1199.1.i = icmp ugt i32 %dec.i.i1204.i, 0
  %cmp55.1.i.i1200.1.i = icmp ugt i32 %dec.i.i1204.i, 0
  %cmp55.2.i.i1201.1.i = icmp ugt i32 %dec.i.i1204.i, 0
  %cmp55.3.i.i1202.1.i = icmp ugt i32 %dec.i.i1204.i, 0
  %3 = xor i1 %cmp55.2.i.i1201.1.i, %cmp55.3.i.i1202.1.i
  %4 = xor i1 %cmp55.1.i.i1200.1.i, %3
  %5 = xor i1 %cmp55.i.i1199.1.i, %4
  %6 = xor i1 %2, %5
  %dec.i.i1204.1.i = add i32 %g_228.promoted166.i1105.i, 0
  %cmp55.i.i1199.2.i = icmp ugt i32 %dec.i.i1204.1.i, 0
  %cmp55.1.i.i1200.2.i = icmp ugt i32 %dec.i.i1204.1.i, 0
  %cmp55.2.i.i1201.2.i = icmp ugt i32 %dec.i.i1204.1.i, 0
  %cmp55.3.i.i1202.2.i = icmp ugt i32 %dec.i.i1204.1.i, 0
  %7 = add i32 0, 0
  %8 = icmp ult i32 %7, 0
  %9 = xor i1 %cmp55.3.i.i1202.2.i, %8
  %10 = xor i1 %cmp55.2.i.i1201.2.i, %9
  %11 = xor i1 %cmp55.1.i.i1200.2.i, %10
  %12 = xor i1 %cmp55.i.i1199.2.i, %11
  %13 = xor i1 %12, %6
  %dec.i.i1204.2.i = add i32 %g_228.promoted166.i1105.i, 0
  %cmp55.i.i1199.3.i = icmp ugt i32 %dec.i.i1204.2.i, 0
  %cmp55.1.i.i1200.3.i = icmp ugt i32 %dec.i.i1204.2.i, 0
  %cmp55.2.i.i1201.3.i = icmp ugt i32 %dec.i.i1204.2.i, 0
  %14 = xor i1 %cmp55.1.i.i1200.3.i, %cmp55.2.i.i1201.3.i
  %15 = xor i1 %cmp55.i.i1199.3.i, %14
  %16 = xor i1 %15, %13
  %17 = zext i1 %16 to i16
  br label %if.then.sink.split.i

for.cond7.preheader.i1132.1.i:                    ; No predecessors!
  br label %if.then.sink.split.i

if.then.sink.split.i:                             ; preds = %for.cond7.preheader.i1132.1.i, %func_135.exit.i
  %xor58.5.i.i1203.3.3.sink.i = phi i16 [ 0, %for.cond7.preheader.i1132.1.i ], [ %17, %func_135.exit.i ]
  ret i32 0
}
```
```
opt: /root/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:10913: llvm::InstructionCost llvm::slpvectorizer::BoUpSLP::ShuffleCostEstimator::finalize(llvm::ArrayRef<int>, llvm::ArrayRef<std::pair<const llvm::slpvectorizer::BoUpSLP::TreeEntry*, unsigned int> >, llvm::ArrayRef<int>, unsigned int, llvm::function_ref<void(llvm::Value*&, llvm::SmallVectorImpl<int>&)>): Assertion `I1 == PoisonMaskElem && "Expected unused subvectors mask"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/opt -o /app/output.s -S -passes=slp-vectorizer <source>
1.	Running pass "function(slp-vectorizer)" on module "<source>"
2.	Running pass "slp-vectorizer" on function "main"
 #0 0x00000000051c9e58 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x51c9e58)
 #1 0x00000000051c785c SignalHandler(int) Signals.cpp:0:0
 #2 0x000078cea7e42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x000078cea7e969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x000078cea7e42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x000078cea7e287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x000078cea7e2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #7 0x000078cea7e39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #8 0x00000000041fda54 llvm::slpvectorizer::BoUpSLP::ShuffleCostEstimator::finalize(llvm::ArrayRef<int>, llvm::ArrayRef<std::pair<llvm::slpvectorizer::BoUpSLP::TreeEntry const*, unsigned int>>, llvm::ArrayRef<int>, unsigned int, llvm::function_ref<void (llvm::Value*&, llvm::SmallVectorImpl<int>&)>) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x41fda54)
 #9 0x00000000042390b0 llvm::InstructionCost llvm::slpvectorizer::BoUpSLP::processBuildVector<llvm::slpvectorizer::BoUpSLP::ShuffleCostEstimator, llvm::InstructionCost, llvm::TargetTransformInfo, llvm::ArrayRef<llvm::Value*>, llvm::slpvectorizer::BoUpSLP, llvm::SmallPtrSetImpl<llvm::Value*>>(llvm::slpvectorizer::BoUpSLP::TreeEntry const*, llvm::Type*, llvm::TargetTransformInfo&, llvm::ArrayRef<llvm::Value*>&, llvm::slpvectorizer::BoUpSLP&, llvm::SmallPtrSetImpl<llvm::Value*>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x42390b0)
#10 0x0000000004243fa7 llvm::slpvectorizer::BoUpSLP::getEntryCost(llvm::slpvectorizer::BoUpSLP::TreeEntry const*, llvm::ArrayRef<llvm::Value*>, llvm::SmallPtrSetImpl<llvm::Value*>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4243fa7)
#11 0x0000000004277f91 llvm::slpvectorizer::BoUpSLP::getTreeCost(llvm::ArrayRef<llvm::Value*>) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4277f91)
#12 0x000000000427da60 (anonymous namespace)::HorizontalReduction::tryToReduce(llvm::slpvectorizer::BoUpSLP&, llvm::DataLayout const&, llvm::TargetTransformInfo*, llvm::TargetLibraryInfo const&) SLPVectorizer.cpp:0:0
#13 0x0000000004280ea9 llvm::SLPVectorizerPass::vectorizeHorReduction(llvm::PHINode*, llvm::Instruction*, llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&, llvm::SmallVectorImpl<llvm::WeakTrackingVH>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4280ea9)
#14 0x000000000428563b llvm::SLPVectorizerPass::vectorizeRootInstruction(llvm::PHINode*, llvm::Instruction*, llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&) (.constprop.0) SLPVectorizer.cpp:0:0
#15 0x0000000004289c9f llvm::SLPVectorizerPass::vectorizeChainsInBlock(llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4289c9f)
#16 0x0000000004290786 llvm::SLPVectorizerPass::runImpl(llvm::Function&, llvm::ScalarEvolution*, llvm::TargetTransformInfo*, llvm::TargetLibraryInfo*, llvm::AAResults*, llvm::LoopInfo*, llvm::DominatorTree*, llvm::AssumptionCache*, llvm::DemandedBits*, llvm::OptimizationRemarkEmitter*) (.part.0) SLPVectorizer.cpp:0:0
#17 0x00000000042912cb llvm::SLPVectorizerPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x42912cb)
#18 0x0000000002fdbfee llvm::detail::PassModel<llvm::Function, llvm::SLPVectorizerPass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x2fdbfee)
#19 0x0000000004fc8d00 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4fc8d00)
#20 0x0000000000e3b51e llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xe3b51e)
#21 0x0000000004fc761b llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4fc761b)
#22 0x0000000000e3abae llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xe3abae)
#23 0x0000000004fc7020 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4fc7020)
#24 0x00000000009177ca llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x9177ca)
#25 0x0000000000909e49 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x909e49)
#26 0x000078cea7e29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#27 0x000078cea7e29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#28 0x0000000000901705 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x901705)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```


Fix patch:
commit a42aa8f265372a15d31a2af10b548fc239ed4b51
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Tue Dec 10 09:19:48 2024 -0800

    [SLP]Fix adjusting of the mask for the fully matched nodes.
    
    When checking for the poison elements in the matches node, need to
    consider the register number, when clearing the corresponding mask
    element.
    
    Fixes #119393

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index c729c6cc9195..d90d7cc8f29e 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -13222,9 +13222,9 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
         copy(CommonMask, Mask.begin());
       }
       // Clear undef scalars.
-      for (int I = 0, Sz = VL.size(); I < Sz; ++I)
+      for (unsigned I : seq<unsigned>(VL.size()))
         if (isa<PoisonValue>(VL[I]))
-          Mask[I] = PoisonMaskElem;
+          Mask[Part * VL.size() + I] = PoisonMaskElem;
       return TargetTransformInfo::SK_PermuteSingleSrc;
     }
     // No perfect match, just shuffle, so choose the first tree node from the


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/X86/full-match-with-poison-scalar.ll
commands: opt -S --passes=slp-vectorizer -slp-threshold=-200 -mtriple=x86_64-unknown-linux-gnu < %s
tests: test_name: test
test_body: define i32 @test() {
entry:
  br label %func_135.exit.i

func_135.exit.i:                                  ; preds = %entry
  %g_228.promoted166.i1105.i = phi i32 [ 0, %entry ]
  %cmp55.i.i1199.i = icmp ugt i32 %g_228.promoted166.i1105.i, 0
  %cmp55.1.i.i1200.i = icmp ugt i32 %g_228.promoted166.i1105.i, 0
  %cmp55.2.i.i1201.i = icmp ugt i32 %g_228.promoted166.i1105.i, 0
  %cmp55.3.i.i1202.i = icmp ugt i32 %g_228.promoted166.i1105.i, 0
  %0 = xor i1 %cmp55.2.i.i1201.i, %cmp55.3.i.i1202.i
  %1 = xor i1 %cmp55.1.i.i1200.i, %0
  %2 = xor i1 %cmp55.i.i1199.i, %1
  %dec.i.i1204.i = add i32 %g_228.promoted166.i1105.i, 0
  %cmp55.i.i1199.1.i = icmp ugt i32 %dec.i.i1204.i, 0
  %cmp55.1.i.i1200.1.i = icmp ugt i32 %dec.i.i1204.i, 0
  %cmp55.2.i.i1201.1.i = icmp ugt i32 %dec.i.i1204.i, 0
  %cmp55.3.i.i1202.1.i = icmp ugt i32 %dec.i.i1204.i, 0
  %3 = xor i1 %cmp55.2.i.i1201.1.i, %cmp55.3.i.i1202.1.i
  %4 = xor i1 %cmp55.1.i.i1200.1.i, %3
  %5 = xor i1 %cmp55.i.i1199.1.i, %4
  %6 = xor i1 %2, %5
  %dec.i.i1204.1.i = add i32 %g_228.promoted166.i1105.i, 0
  %cmp55.i.i1199.2.i = icmp ugt i32 %dec.i.i1204.1.i, 0
  %cmp55.1.i.i1200.2.i = icmp ugt i32 %dec.i.i1204.1.i, 0
  %cmp55.2.i.i1201.2.i = icmp ugt i32 %dec.i.i1204.1.i, 0
  %cmp55.3.i.i1202.2.i = icmp ugt i32 %dec.i.i1204.1.i, 0
  %7 = add i32 0, 0
  %8 = icmp ult i32 %7, 0
  %9 = xor i1 %cmp55.3.i.i1202.2.i, %8
  %10 = xor i1 %cmp55.2.i.i1201.2.i, %9
  %11 = xor i1 %cmp55.1.i.i1200.2.i, %10
  %12 = xor i1 %cmp55.i.i1199.2.i, %11
  %13 = xor i1 %12, %6
  %dec.i.i1204.2.i = add i32 %g_228.promoted166.i1105.i, 0
  %cmp55.i.i1199.3.i = icmp ugt i32 %dec.i.i1204.2.i, 0
  %cmp55.1.i.i1200.3.i = icmp ugt i32 %dec.i.i1204.2.i, 0
  %cmp55.2.i.i1201.3.i = icmp ugt i32 %dec.i.i1204.2.i, 0
  %14 = xor i1 %cmp55.1.i.i1200.3.i, %cmp55.2.i.i1201.3.i
  %15 = xor i1 %cmp55.i.i1199.3.i, %14
  %16 = xor i1 %15, %13
  %17 = zext i1 %16 to i16
  br label %if.then.sink.split.i

for.cond7.preheader.i1132.1.i:                    ; No predecessors!
  br label %if.then.sink.split.i

if.then.sink.split.i:                             ; preds = %for.cond7.preheader.i1132.1.i, %func_135.exit.i
  %xor58.5.i.i1203.3.3.sink.i = phi i16 [ 0, %for.cond7.preheader.i1132.1.i ], [ %17, %func_135.exit.i ]
  ret i32 0
}