Bug type: crash
Component: LoopVectorize
Bug location: llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp: PlainCFGBuilder::createVPInstructionsForVPBB
Issue title: [Loop Vectorizer] Unhandled opcode UNREACHABLE executed at /root/llvm-project/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp:257!
Labels: vectorizers
crash
Reported by: k-arrows

Reproducer:
https://godbolt.org/z/M3rojTjfc

Backtrace:
```console
Unhandled opcode
UNREACHABLE executed at /root/llvm-project/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp:257!
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=loop-vectorize <source>
1.	Running pass "function(loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>)" on module "<source>"
2.	Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "switch"
 #0 0x00000000057a4688 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x57a4688)
 #1 0x00000000057a1534 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #2 0x0000705e12842520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x0000705e128969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x0000705e12842476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x0000705e128287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x00000000056db7aa (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x56db7aa)
 #7 0x00000000036a2db0 llvm::VPTypeAnalysis::inferScalarTypeForRecipe(llvm::VPReplicateRecipe const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x36a2db0)
 #8 0x00000000036a295c llvm::VPTypeAnalysis::inferScalarType(llvm::VPValue const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x36a295c)
 #9 0x000000000372765d (anonymous namespace)::VPlanVerifier::verifyVPBasicBlock(llvm::VPBasicBlock const*) VPlanVerifier.cpp:0:0
#10 0x0000000003729f01 (anonymous namespace)::VPlanVerifier::verifyBlock(llvm::VPBlockBase const*) VPlanVerifier.cpp:0:0
#11 0x000000000372b34a (anonymous namespace)::VPlanVerifier::verifyRegionRec(llvm::VPRegionBlock const*) VPlanVerifier.cpp:0:0
#12 0x000000000372d952 llvm::verifyVPlanIsValid(llvm::VPlan const&, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x372d952)
#13 0x000000000352ce13 llvm::LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(std::unique_ptr<llvm::VPlan, std::default_delete<llvm::VPlan>>, llvm::VFRange&, llvm::LoopVersioning*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x352ce13)
#14 0x000000000352d428 llvm::LoopVectorizationPlanner::buildVPlansWithVPRecipes(llvm::ElementCount, llvm::ElementCount) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x352d428)
#15 0x000000000352dd34 llvm::LoopVectorizationPlanner::plan(llvm::ElementCount, unsigned int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x352dd34)
#16 0x0000000003531b77 llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3531b77)
#17 0x0000000003534da0 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3534da0)
#18 0x000000000353544d llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x353544d)
#19 0x0000000002e2b1ee llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x2e2b1ee)
#20 0x00000000055904d1 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x55904d1)
#21 0x0000000000ee0cbe 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+0xee0cbe)
#22 0x000000000558ea3a llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x558ea3a)
#23 0x000000000096d5ae 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+0x96d5ae)
#24 0x000000000558e3f1 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x558e3f1)
#25 0x00000000009778a8 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, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x9778a8)
#26 0x000000000096b917 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x96b917)
#27 0x0000705e12829d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#28 0x0000705e12829e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#29 0x0000000000962a35 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x962a35)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```

Comments: author: k-arrows
body: This comes from the following:
https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/LoopUnroll/full-unroll-crashers.ll

Fix patch:
commit fe6e17840159f7ae9785d8506ff2987a2df7ab08
Author: Luke Lau <luke@igalia.com>
Date:   Mon Sep 8 17:01:43 2025 +0800

    [VPlan] Don't build recipes for unconditional switches (#157323)
    
    In #157322 we crash because we try to infer a type for a VPReplicate
    switch recipe.
    
    My understanding was that these switches should be removed by
    VPlanPredicator, but this switch survived through it because it was
    unconditional, i.e. had no cases other than the default case.
    
    This fixes #157322 by not emitting any recipes for unconditional
    switches to begin with, similar to how we treat unconditional branches.

diff --git a/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp b/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
index c1c525ee2312..cef91c15dd87 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp
@@ -193,6 +193,9 @@ void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
     }
 
     if (auto *SI = dyn_cast<SwitchInst>(Inst)) {
+      // Don't emit recipes for unconditional switch instructions.
+      if (SI->getNumCases() == 0)
+        continue;
       SmallVector<VPValue *> Ops = {getOrCreateVPOperand(SI->getCondition())};
       for (auto Case : SI->cases())
         Ops.push_back(getOrCreateVPOperand(Case.getCaseValue()));


Regression tests:
file: llvm/test/Transforms/LoopVectorize/predicate-switch.ll
commands: opt -p loop-vectorize -force-vector-width=2 -force-vector-interleave=1 -S %s
opt -p loop-vectorize -force-vector-width=2 -force-vector-interleave=2 -S %s
tests: test_name: switch_unconditional
test_body: define void @switch_unconditional(ptr %start) {
entry:
  br label %loop

loop:                                             ; preds = %latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
  %gep = getelementptr i32, ptr %start, i64 %iv
  %x = load i32, ptr %gep, align 4
  switch i32 %x, label %foo [
  ]

foo:                                              ; preds = %loop
  br label %latch

latch:                                            ; preds = %foo
  store i32 0, ptr %gep, align 4
  %iv.next = add i64 %iv, 1
  %cmp = icmp eq i64 %iv.next, 100
  br i1 %cmp, label %exit, label %loop

exit:                                             ; preds = %latch
  ret void
}