Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: BoUpSLP::canMapToVector
Issue title: Crash on slp-vectorizer
Labels: llvm:SLPVectorizer
crash
Reported by: edg-l

When running `/opt/llvm-19/bin/opt -O3 -S bug.ll` opt crashes with the following:

(tested on 19 rc2 and rc4 and 18)
```
/opt/llvm-19/bin/llvm-config --version
19.1.0-rc2

/opt/llvm-19/bin/opt: WARNING: failed to create target machine for 'arm64-apple-darwin23.6.0': unable to get target for 'arm64-apple-darwin23.6.0', see --version and --triple.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/llvm-19/bin/opt -O3 -S bug.ll
1.	Running pass "function<eager-inv>(float2int,lower-constant-intrinsics,chr,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-unroll<O3>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch;speculate-unpredictables>)" on module "lol.ll"
2.	Running pass "slp-vectorizer" on function "bug"
 #0 0x00005558779163f7 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/admin/repos/llvm-project/llvm/lib/Support/Unix/Signals.inc:723:13
 #1 0x0000555877914570 llvm::sys::RunSignalHandlers() /home/admin/repos/llvm-project/llvm/lib/Support/Signals.cpp:106:18
 #2 0x0000555877916d9a SignalHandler(int) /home/admin/repos/llvm-project/llvm/lib/Support/Unix/Signals.inc:413:1
 #3 0x00007fb7b7e5b050 (/lib/x86_64-linux-gnu/libc.so.6+0x3c050)
 #4 0x0000555878d08ae0 llvm::slpvectorizer::BoUpSLP::canMapToVector(llvm::Type*) const /home/admin/repos/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:0:0
 #5 0x0000555878d3ca29 llvm::SLPVectorizerPass::vectorizeInsertValueInst(llvm::InsertValueInst*, llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&, bool) /home/admin/repos/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:18336:8
 #6 0x0000555878d3d459 llvm::SLPVectorizerPass::vectorizeInserts(llvm::SmallSetVector<llvm::Instruction*, 8u>&, llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&) /home/admin/repos/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:0:11
 #7 0x0000555878d3e35b llvm::SLPVectorizerPass::vectorizeChainsInBlock(llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&)::$_172::operator()(bool) const /home/admin/repos/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:18847:20
 #8 0x0000555878d34039 llvm::SLPVectorizerPass::vectorizeChainsInBlock(llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&) /home/admin/repos/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:18963:18
 #9 0x0000555878d31968 llvm::SLPVectorizerPass::runImpl(llvm::Function&, llvm::ScalarEvolution*, llvm::TargetTransformInfo*, llvm::TargetLibraryInfo*, llvm::AAResults*, llvm::LoopInfo*, llvm::DominatorTree*, llvm::AssumptionCache*, llvm::DemandedBits*, llvm::OptimizationRemarkEmitter*) /home/admin/repos/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:15865:13
#10 0x0000555878d31431 llvm::SLPVectorizerPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /home/admin/repos/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:15796:18
#11 0x0000555878921dfd llvm::detail::PassModel<llvm::Function, llvm::SLPVectorizerPass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /home/admin/repos/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:90:5
#12 0x0000555877ab570d llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /home/admin/repos/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:85:8
#13 0x00005558785d887d llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) /home/admin/repos/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:90:5
#14 0x0000555877ab94f0 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /home/admin/repos/llvm-project/llvm/lib/IR/PassManager.cpp:129:23
#15 0x00005558785d86cd llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /home/admin/repos/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:90:5
#16 0x0000555877ab44ed llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /home/admin/repos/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h:85:8
#17 0x00005558788ca8c9 llvm::SmallPtrSetImplBase::isSmall() const /home/admin/repos/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:197:33
#18 0x00005558788ca8c9 llvm::SmallPtrSetImplBase::~SmallPtrSetImplBase() /home/admin/repos/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h:84:10
#19 0x00005558788ca8c9 llvm::PreservedAnalyses::~PreservedAnalyses() /home/admin/repos/llvm-project/llvm/include/llvm/IR/Analysis.h:111:7
#20 0x00005558788ca8c9 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) /home/admin/repos/llvm-project/llvm/tools/opt/NewPMDriver.cpp:547:3
#21 0x00005558778e5779 optMain /home/admin/repos/llvm-project/llvm/tools/opt/optdriver.cpp:739:12
#22 0x00007fb7b7e4624a (/lib/x86_64-linux-gnu/libc.so.6+0x2724a)
#23 0x00007fb7b7e46305 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x27305)
#24 0x00005558778dfd21 _start (/opt/llvm-19/bin/opt+0xf17d21)
Segmentation fault
```

```llvmir
; ModuleID = 'LLVMDialectModule'
source_filename = "LLVMDialectModule"
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "arm64-apple-darwin23.6.0"

define { { {}, {}, {}, {}, {}, {}, {} } } @"bug"({ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, { {}, {}, {}, {}, {}, {}, {} }, { {} } } %0) {
  %2 = extractvalue { {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, { {}, {}, {}, {}, {}, {}, {} }, { {} } } %0, 18
  %3 = insertvalue { { {}, {}, {}, {}, {}, {}, {} } } undef, { {}, {}, {}, {}, {}, {}, {} } %2, 0
  ret { { {}, {}, {}, {}, {}, {}, {} } } %3
}

!llvm.module.flags = !{!0}

!0 = !{i32 2, !"Debug Info Version", i32 3}
```

Comments: author: edg-l
body: one question, will this be included in llvm 19?
author: alexey-bataev
body: Not sure, it is not an immediate regression from 18 to 19, and it is too late, I think, to include it into 19

Fix patch:
commit d65ff3e9364536f9e0bd5f1c1bace626c256a2ad
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Wed Sep 4 05:12:17 2024 -0700

    [SLP]Fix PR107198: add a check for empty complex type
    
    Need to check if the complex type is empty before trying to dig in,
    trying to find vectorizable type
    
    Fixes https://github.com/llvm/llvm-project/issues/107198

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 19b95cf473e9..a2af7f4e1b01 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -7780,6 +7780,8 @@ unsigned BoUpSLP::canMapToVector(Type *T) const {
   Type *EltTy = T;
 
   while (isa<StructType, ArrayType, FixedVectorType>(EltTy)) {
+    if (EltTy->isEmptyTy())
+      return 0;
     if (auto *ST = dyn_cast<StructType>(EltTy)) {
       // Check that struct is homogeneous.
       for (const auto *Ty : ST->elements())


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/empty-struct.ll
commands: opt -S --passes=slp-vectorizer < %s
tests: test_name: test
test_body: define { { {}, {}, {}, {}, {}, {}, {} } } @test({ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, { {}, {}, {}, {}, {}, {}, {} }, { {} } } %0) {
  %2 = extractvalue { {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, { {}, {}, {}, {}, {}, {}, {} }, { {} } } %0, 18
  %3 = insertvalue { { {}, {}, {}, {}, {}, {}, {} } } undef, { {}, {}, {}, {}, {}, {}, {} } %2, 0
  ret { { {}, {}, {}, {}, {}, {}, {} } } %3
}