Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: BoUpSLP::isTreeTinyAndNotFullyVectorizable
Issue title: Assertion `((GatheredLoadsEntriesFirst.has_value() && E->getOpcode() == Instruction::Load && E->isGather() && E->Idx < *GatheredLoadsEntriesFirst) || all_of(E->Scalars, [=](Value *V) -> bool { if (E->getOpcode() == Instruction::GetElementPtr && !isa<GetElementPtrInst>(V)) return true; auto *I = cast<Instruction>(V); return !E->isOpcodeOrAlt(I) || I->getParent() == BB || isVectorLikeInstWithConstOps(I); })) && "Expected gathered loads or GEPs or instructions from same basic " "block."' failed.
Labels: llvm:SLPVectorizer
crash
Reported by: TatyanaDoubts

To reproduce the test below with -passes slp-vectorizer -slp-threshold=-99999 
```
; ModuleID = './reduced.ll'
source_filename = "./reduced.ll"
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-ni:1-p2:32:8:8:32-ni:2"
target triple = "x86_64-unknown-linux-gnu"

define i32 @wombat(i32 %arg, i32 %arg1) #0 gc "statepoint-example" {
bb:
  %zext = zext i32 %arg1 to i64
  %zext2 = zext i32 %arg to i64
  %sext = sext i32 %arg to i64
  br label %bb3

bb3:                                              ; preds = %bb
  %getelementptr = getelementptr i64, ptr addrspace(1) null, i64 %zext
  %getelementptr4 = getelementptr i64, ptr addrspace(1) null, i64 %zext2
  %getelementptr5 = getelementptr i64, ptr addrspace(1) null, i64 %sext
  %zext6 = zext i32 0 to i64
  %getelementptr7 = getelementptr i64, ptr addrspace(1) null, i64 %zext6
  ret i32 0
}

attributes #0 = { "target-features"="+prfchw,-cldemote,+avx,+aes,+sahf,+pclmul,-xop,+crc32,+xsaves,-avx512fp16,-usermsr,-sm4,-egpr,+sse4.1,-avx512ifma,+xsave,+sse4.2,-tsxldtrk,-sm3,-ptwrite,-widekl,+invpcid,+64bit,+xsavec,-avx10.1-512,-avx512vpopcntdq,+cmov,-avx512vp2intersect,+avx512cd,+movbe,-avxvnniint8,-ccmp,-amx-int8,-kl,-avx10.1-256,+evex512,-avxvnni,+rtm,+adx,+avx2,-hreset,-movdiri,-serialize,-sha512,-vpclmulqdq,+avx512vl,-uintr,-cf,+clflushopt,-raoint,-cmpccxadd,+bmi,-amx-tile,+sse,-avx10.2-256,-gfni,-avxvnniint16,-amx-fp16,-zu,-ndd,+xsaveopt,+rdrnd,+avx512f,-amx-bf16,-avx512bf16,-avx512vnni,-push2pop2,+cx8,+avx512bw,+sse3,+pku,-nf,+fsgsbase,-clzero,-mwaitx,-lwp,+lzcnt,-sha,-movdir64b,-ppx,-wbnoinvd,-enqcmd,-avx10.2-512,-avxneconvert,-tbm,-pconfig,-amx-complex,+ssse3,+cx16,+bmi2,+fma,+popcnt,-avxifma,+f16c,-avx512bitalg,-rdpru,+clwb,+mmx,+sse2,+rdseed,-avx512vbmi2,-prefetchi,-rdpid,-fma4,-avx512vbmi,-shstk,-vaes,-waitpkg,-sgx,+fxsr,+avx512dq,-sse4a,-avx512f" }

```
Reproducer: https://godbolt.org/z/8WhP4hY6G

Stack dump:
```
opt: /root/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:13048: llvm::Instruction& llvm::slpvectorizer::BoUpSLP::getLastInstructionInBundle(const llvm::slpvectorizer::BoUpSLP::TreeEntry*): Assertion `((GatheredLoadsEntriesFirst.has_value() && E->getOpcode() == Instruction::Load && E->isGather() && E->Idx < *GatheredLoadsEntriesFirst) || all_of(E->Scalars, [=](Value *V) -> bool { if (E->getOpcode() == Instruction::GetElementPtr && !isa<GetElementPtrInst>(V)) return true; auto *I = cast<Instruction>(V); return !E->isOpcodeOrAlt(I) || I->getParent() == BB || isVectorLikeInstWithConstOps(I); })) && "Expected gathered loads or GEPs or instructions from same basic " "block."' 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 -slp-threshold=-99999 <source>
1.	Running pass "function(slp-vectorizer)" on module "<source>"
2.	Running pass "slp-vectorizer" on function "wombat"
 #0 0x00000000050d8608 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x50d8608)
 #1 0x00000000050d5fbc SignalHandler(int) Signals.cpp:0:0
 #2 0x000070a067c42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x000070a067c969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x000070a067c42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x000070a067c287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x000070a067c2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #7 0x000070a067c39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #8 0x0000000004157831 llvm::slpvectorizer::BoUpSLP::getLastInstructionInBundle(llvm::slpvectorizer::BoUpSLP::TreeEntry const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4157831)
 #9 0x0000000004157890 llvm::slpvectorizer::BoUpSLP::setInsertPointAfterBundle(llvm::slpvectorizer::BoUpSLP::TreeEntry const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4157890)
#10 0x00000000041820da llvm::slpvectorizer::BoUpSLP::vectorizeTree(llvm::slpvectorizer::BoUpSLP::TreeEntry*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x41820da)
#11 0x00000000041a7a5c llvm::slpvectorizer::BoUpSLP::vectorizeTree(llvm::SmallDenseSet<llvm::Value*, 4u, llvm::DenseMapInfo<llvm::Value*, void>> const&, llvm::Instruction*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x41a7a5c)
#12 0x00000000041ab4ad llvm::slpvectorizer::BoUpSLP::vectorizeTree() (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x41ab4ad)
#13 0x00000000041c0e45 llvm::SLPVectorizerPass::tryToVectorizeList(llvm::ArrayRef<llvm::Value*>, llvm::slpvectorizer::BoUpSLP&, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x41c0e45)
#14 0x00000000041c2f7b llvm::SLPVectorizerPass::vectorizeGEPIndices(llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x41c2f7b)
#15 0x00000000041cf257 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
#16 0x00000000041cfedb llvm::SLPVectorizerPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x41cfedb)
#17 0x0000000002f64f0e 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+0x2f64f0e)
#18 0x0000000004ed9788 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4ed9788)
#19 0x0000000000e2773e 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+0xe2773e)
#20 0x0000000004ed81ae llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4ed81ae)
#21 0x0000000000e26e8e 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+0xe26e8e)
#22 0x0000000004ed7be0 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4ed7be0)
#23 0x000000000090a07a 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+0x90a07a)
#24 0x00000000008fce7c optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8fce7c)
#25 0x000070a067c29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#26 0x000070a067c29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#27 0x00000000008f493e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8f493e)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```


Fix patch:
commit a3508e0246741851f06cb9ba86203be8d89febed
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Wed Oct 23 10:25:41 2024 -0700

    [SLP]Small buidlvector only graph should contains scalars from same block
    
    If the graph is small and has single buildvector node, all scalars
    instructions must be from the same basic block to prevent compiler
    crash.
    
    Fixes #113451

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 756b25ac9856..d824c40c401d 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11588,7 +11588,8 @@ bool BoUpSLP::isTreeTinyAndNotFullyVectorizable(bool ForReduction) const {
 
   if (VectorizableTree.back()->isGather() &&
       VectorizableTree.back()->isAltShuffle() &&
-      VectorizableTree.back()->getVectorFactor() > 2)
+      VectorizableTree.back()->getVectorFactor() > 2 &&
+      allSameBlock(VectorizableTree.back()->Scalars))
     return false;
 
   assert(VectorizableTree.empty()


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/X86/small-graph-diff-block-instructions.ll
commands: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -mattr=+avx512dq -slp-threshold=-99999 < %s
tests: test_name: test
test_body: define i32 @test(i32 %arg, i32 %arg1) {
bb:
  %zext = zext i32 %arg1 to i64
  %zext2 = zext i32 %arg to i64
  %sext = sext i32 %arg to i64
  br label %bb3

bb3:                                              ; preds = %bb
  %getelementptr = getelementptr i64, ptr addrspace(1) null, i64 %zext
  %getelementptr4 = getelementptr i64, ptr addrspace(1) null, i64 %zext2
  %getelementptr5 = getelementptr i64, ptr addrspace(1) null, i64 %sext
  %zext6 = zext i32 0 to i64
  %getelementptr7 = getelementptr i64, ptr addrspace(1) null, i64 %zext6
  ret i32 0
}