Bug type: crash
Component: LoopVectorize
Bug location: llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp: scalarizeInstruction
Issue title: [LoopVectorize] Assertion `State.TypeAnalysis.inferScalarType(RepRecipe) == Cloned->getType() && "inferred type and type from generated instructions do not match"' failed.
Labels: vectorizers
crash
Reported by: ewlu

Testcase:
```llvm ir
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"

@b = external global [0 x i16]
@n = internal global i16 9
@u = external global [9 x i64]
@p = external global [9 x i16]

define i64 @c(i8 %k, i16 %n, ptr %p, ptr %u, ptr %w, i64 %indvars.iv133, i8 %sub, i8 %add98.us.us.us) {
entry:
  %arrayidx36 = getelementptr i8, ptr %u, i64 64
  br label %for.cond18.preheader.us.us.us

for.cond18.preheader.us.us.us:                    ; preds = %cond.false.us.us.us, %entry
  br label %cond.false.us.us.us

cond.false.us.us.us:                              ; preds = %for.body27.us.us.us, %for.cond18.preheader.us.us.us
  %ah.0.us.us.us = phi i32 [ %add67.us.us.us, %for.body27.us.us.us ], [ 0, %for.cond18.preheader.us.us.us ]
  %0 = load i16, ptr %p, align 2
  %conv22.us.us.us = sext i16 %0 to i32
  %cmp24.us.us.us = icmp slt i32 %ah.0.us.us.us, %conv22.us.us.us
  br i1 %cmp24.us.us.us, label %for.body27.us.us.us, label %for.cond18.preheader.us.us.us

for.body27.us.us.us:                              ; preds = %cond.false.us.us.us
  %1 = load i16, ptr %w, align 2
  %tobool.not.us.us.us = icmp eq i16 %1, 0
  %narrow.us.us.us = select i1 %tobool.not.us.us.us, i16 0, i16 %n
  %cond35.us.us.us = sext i16 %narrow.us.us.us to i32
  %2 = load i64, ptr %arrayidx36, align 8
  %conv37.us.us.us = trunc i64 %2 to i32
  %cond43.us.us.us = tail call i32 @llvm.smin.i32(i32 %cond35.us.us.us, i32 %conv37.us.us.us)
  %conv46.us.us.us = trunc i32 %cond43.us.us.us to i16
  store i16 %conv46.us.us.us, ptr @b, align 2
  %3 = load i8, ptr %w, align 1
  %conv54.us.us.us = sext i8 %3 to i16
  store i16 %conv54.us.us.us, ptr %u, align 2
  %add67.us.us.us = add i32 %ah.0.us.us.us, 1
  br label %cond.false.us.us.us
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.smin.i32(i32, i32) #0

define i64 @main(ptr %k) #1 {
entry:
  store i64 57, ptr getelementptr inbounds nuw (i8, ptr @u, i64 64), align 32
  %0 = load i16, ptr @n, align 2
  %1 = call i64 @c(i8 0, i16 %0, ptr @p, ptr @u, ptr %k, i64 0, i8 0, i8 0)
  ret i64 %1
}

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #1 = { "target-features"="+v" }
```

Commands/backtrace
```
$ /scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt "-passes=lto<O3>" reduced.ll
WARNING: You're attempting to print out a bitcode file.
This is inadvisable as it may cause display problems. If
you REALLY want to taste LLVM bitcode first-hand, you
can force output with the `-f' option.

opt: /scratch/ewlu/daily-upstream-build/llvm/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp:2842: void scalarizeInstruction(const llvm::Instruction*, llvm::VPReplicateRecipe*, const llvm::VPLane&, llvm::VPTransformState&): Assertion `State.TypeAnalysis.inferScalarType(RepRecipe) == Cloned->getType() && "inferred type and type from generated instructions do not match"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: /scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt -passes=lto<O3> reduced.ll
1.      Running pass "function<eager-inv>(loop-mssa(licm<allowspeculation>),gvn<>,memcpyopt,dse,move-auto-init,mldst-motion<no-split-footer-bb>,loop(indvars,loop-deletion,loop-unroll-full),loop-distribute,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-unroll<O3>,transform-warning,sroa<preserve-cfg>,instcombine<max-iterations=1;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;no-hoist-loads-stores-with-cond-faulting;sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>,sccp,instcombine<max-iterations=1;no-verify-fixpoint>,bdce,slp-vectorizer,vector-combine,infer-alignment,instcombine<max-iterations=1;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop(evl-iv-simplify),jump-threading)" on module "reduced.ll"
2.      Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "main"
 #0 0x0000645af6577e72 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x338ee72)
 #1 0x0000645af6574b6f llvm::sys::RunSignalHandlers() (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x338bb6f)
 #2 0x0000645af6574cbc SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x000079da8fc45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x000079da8fc9eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x000079da8fc9eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x000079da8fc9eb2c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x000079da8fc4527e raise ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x000079da8fc288ff abort ./stdlib/abort.c:81:7
 #9 0x000079da8fc2881b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x000079da8fc3b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#11 0x0000645af4394a5d (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x11aba5d)
#12 0x0000645af43986a3 llvm::VPReplicateRecipe::execute(llvm::VPTransformState&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x11af6a3)
#13 0x0000645af433bee1 llvm::VPBasicBlock::executeRecipes(llvm::VPTransformState*, llvm::BasicBlock*) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x1152ee1)
#14 0x0000645af43510d7 llvm::VPBasicBlock::execute(llvm::VPTransformState*) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x11680d7)
#15 0x0000645af43582c1 llvm::VPlan::execute(llvm::VPTransformState*) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x116f2c1)
#16 0x0000645af41d802f llvm::LoopVectorizationPlanner::executePlan(llvm::ElementCount, unsigned int, llvm::VPlan&, llvm::InnerLoopVectorizer&, llvm::DominatorTree*, bool) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0xfef02f)
#17 0x0000645af41e69f7 llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0xffd9f7)
#18 0x0000645af41e96a1 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x10006a1)
#19 0x0000645af41e9c67 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x1000c67)
#20 0x0000645af3a81535 llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x898535)
#21 0x0000645af635bb7d llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x3172b7d)
#22 0x0000645af3a83d15 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x89ad15)
#23 0x0000645af635bf67 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x3172f67)
#24 0x0000645af3719fe5 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x530fe5)
#25 0x0000645af635d10d llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x317410d)
#26 0x0000645af3726099 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) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x53d099)
#27 0x0000645af37181a8 optMain (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x52f1a8)
#28 0x000079da8fc2a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#29 0x000079da8fc2a28b call_init ./csu/../csu/libc-start.c:128:20
#30 0x000079da8fc2a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#31 0x0000645af370e0b5 _start (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x5250b5)
Aborted (core dumped)
```

Godbolt: https://godbolt.org/z/T3cbfY9zG

Found via fuzzer (C program before reduction)


Fix patch:
commit 39c30665e99145e07b0170b552f18371a67b2e03
Author: Florian Hahn <flo@fhahn.com>
Date:   Sat Aug 2 19:49:59 2025 +0100

    [VPlan] Update type of cloned instruction in scalarizeInstruction.
    
    The operands of the replicate recipe may have been narrowed, resulting
    in a narrower result type. Update the type of the cloned instruction to
    the correct type.
    
    Fixes https://github.com/llvm/llvm-project/issues/151392.

diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 11b4677ec102..98d11f0bc789 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -2836,12 +2836,12 @@ static void scalarizeInstruction(const Instruction *Instr,
   Instruction *Cloned = Instr->clone();
   if (!IsVoidRetTy) {
     Cloned->setName(Instr->getName() + ".cloned");
-#if !defined(NDEBUG)
-    // Verify that VPlan type inference results agree with the type of the
-    // generated values.
-    assert(State.TypeAnalysis.inferScalarType(RepRecipe) == Cloned->getType() &&
-           "inferred type and type from generated instructions do not match");
-#endif
+    Type *ResultTy = State.TypeAnalysis.inferScalarType(RepRecipe);
+    // The operands of the replicate recipe may have been narrowed, resulting in
+    // a narrower result type. Update the type of the cloned instruction to the
+    // correct type.
+    if (ResultTy != Cloned->getType())
+      Cloned->mutateType(ResultTy);
   }
 
   RepRecipe->applyFlags(*Cloned);


Regression tests:
file: llvm/test/Transforms/LoopVectorize/single-scalar-cast-minbw.ll
commands: opt -passes=loop-vectorize -force-vector-width=4 -S %s
tests: test_name: single_scalar_cast_stored
test_body: define void @single_scalar_cast_stored(ptr %src, ptr %dst, i32 %n) {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
  %l = load i16, ptr %src, align 2
  %cmp = icmp eq i16 %l, 0
  %l.ext = zext i16 %l to i32
  %and = and i32 %l.ext, 15
  %sel = select i1 %cmp, i32 0, i32 %and
  %sel.trunc = trunc i32 %sel to i16
  store i16 %sel.trunc, ptr %dst, align 2
  %iv.next = add nuw i32 %iv, 1
  %ec = icmp ne i32 %iv.next, %n
  br i1 %ec, label %loop, label %exit

exit:                                             ; preds = %loop
  ret void
}