Bug type: crash
Component: LoopVectorize
Bug location: llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp: VPFirstOrderRecurrencePHIRecipe::computeCost
Issue title: opt -passes="loop-vectorize" -pass-remarks-output=tmp.opts crashes with 'Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.'
Labels: vectorizers
crash
Reported by: mikaelholmen

llvm commit: 10b048c8922d
Reproduce with: ```opt -passes="loop-vectorize" bbi-101140.ll -o /dev/null -pass-remarks-output=tmp.opts```
Result:
```
opt: ../include/llvm/Support/Casting.h:578: decltype(auto) llvm::cast(From *) [To = llvm::VectorType, From = llvm::Type]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: build-all/bin/opt -passes=loop-vectorize bbi-101140.ll -o /dev/null -pass-remarks-output=tmp.opts
1.	Running pass "function(loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>)" on module "bbi-101140.ll"
2.	Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "main"
 #0 0x000055b814f24938 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (build-all/bin/opt+0x4435938)
 #1 0x000055b814f223fe llvm::sys::RunSignalHandlers() (build-all/bin/opt+0x44333fe)
 #2 0x000055b814f2516d SignalHandler(int) Signals.cpp:0:0
 #3 0x00007f5d1b5dbcf0 __restore_rt (/lib64/libpthread.so.0+0x12cf0)
 #4 0x00007f5d19194acf raise (/lib64/libc.so.6+0x4eacf)
 #5 0x00007f5d19167ea5 abort (/lib64/libc.so.6+0x21ea5)
 #6 0x00007f5d19167d79 _nl_load_domain.cold.0 (/lib64/libc.so.6+0x21d79)
 #7 0x00007f5d1918d426 (/lib64/libc.so.6+0x47426)
 #8 0x000055b816474525 llvm::VPFirstOrderRecurrencePHIRecipe::computeCost(llvm::ElementCount, llvm::VPCostContext&) const (build-all/bin/opt+0x5985525)
 #9 0x000055b816461f4c llvm::VPRecipeBase::cost(llvm::ElementCount, llvm::VPCostContext&) (build-all/bin/opt+0x5972f4c)
#10 0x000055b8163faa3a llvm::LoopVectorizationPlanner::emitInvalidCostRemarks(llvm::OptimizationRemarkEmitter*) (build-all/bin/opt+0x590ba3a)
#11 0x000055b816427189 llvm::LoopVectorizePass::processLoop(llvm::Loop*) (build-all/bin/opt+0x5938189)
#12 0x000055b81642cd0b llvm::LoopVectorizePass::runImpl(llvm::Function&) (build-all/bin/opt+0x593dd0b)
#13 0x000055b81642d568 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (build-all/bin/opt+0x593e568)
#14 0x000055b8162e33dd llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) PassBuilderPipelines.cpp:0:0
#15 0x000055b81512d317 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (build-all/bin/opt+0x463e317)
#16 0x000055b8162dcf6d llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) PassBuilderPipelines.cpp:0:0
#17 0x000055b815131ea6 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (build-all/bin/opt+0x4642ea6)
#18 0x000055b8162d6a0d llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) PassBuilderPipelines.cpp:0:0
#19 0x000055b81512c047 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (build-all/bin/opt+0x463d047)
#20 0x000055b81627ab63 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) (build-all/bin/opt+0x578bb63)
#21 0x000055b814eebd0a optMain (build-all/bin/opt+0x43fcd0a)
#22 0x00007f5d19180d85 __libc_start_main (/lib64/libc.so.6+0x3ad85)
#23 0x000055b814ee5b2e _start (build-all/bin/opt+0x43f6b2e)
Abort (core dumped)
```
[bbi-101140.ll.gz](https://github.com/user-attachments/files/17774956/bbi-101140.ll.gz)


Comments: author: mikaelholmen
body: This starts happening with https://github.com/llvm/llvm-project/commit/680901ed8010319843cd81275b845d682f77e27f
```
[VPlan] Implement VPHeaderPHIRecipe::computeCost.

Fill out computeCost implementations for various header PHI recipes,
matching the legacy cost model for now.
```
author: mikaelholmen
body: Thanks!

Fix patch:
commit 320038579d3c23b78f99618b71640f51423fe321
Author: Florian Hahn <flo@fhahn.com>
Date:   Thu Nov 21 21:11:20 2024 +0000

    [VPlan] Return cost of PHI for scalar VFs in computeCost for FORs.
    
    This fixes a crash when the VF is scalar.
    
    Fixes https://github.com/llvm/llvm-project/issues/116375.

diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 71aca3be9e5d..24cf4666c62c 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -3317,6 +3317,10 @@ void VPFirstOrderRecurrencePHIRecipe::execute(VPTransformState &State) {
 InstructionCost
 VPFirstOrderRecurrencePHIRecipe::computeCost(ElementCount VF,
                                              VPCostContext &Ctx) const {
+  TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
+  if (VF.isScalar())
+  return Ctx.TTI.getCFInstrCost(Instruction::PHI, CostKind);
+
   if (VF.isScalable() && VF.getKnownMinValue() == 1)
     return InstructionCost::getInvalid();
 
@@ -3325,7 +3329,6 @@ VPFirstOrderRecurrencePHIRecipe::computeCost(ElementCount VF,
   Type *VectorTy =
       ToVectorTy(Ctx.Types.inferScalarType(this->getVPSingleValue()), VF);
 
-  TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
   return Ctx.TTI.getShuffleCost(TargetTransformInfo::SK_Splice,
                                 cast<VectorType>(VectorTy), Mask, CostKind,
                                 VF.getKnownMinValue() - 1);


Regression tests:
file: llvm/test/Transforms/LoopVectorize/AArch64/invalid-costs.ll
commands: opt -passes="loop-vectorize" -pass-remarks-output=/dev/stderr -S %s
tests: test_name: <module>
test_body: 
; REMARKS: the cost-model indicates that vectorization is not beneficial

; Test for https://github.com/llvm/llvm-project/issues/116375.
define void @test_i24_load_for(ptr noalias %src, ptr %dst) {
;
entry:
  br label %loop

loop:
  %iv = phi i16 [ 0, %entry ], [ %iv.next, %loop ]
  %for = phi i24 [ 0, %entry ], [ %for.next, %loop ]
  %iv.next = add i16 %iv, 1
  %gep.src = getelementptr inbounds i24, ptr %src, i16 %iv
  %for.next = load i24, ptr %gep.src, align 1
  %gep.dst = getelementptr inbounds i24, ptr %dst, i16 %iv
  store i24 %for, ptr %gep.dst
  %ec = icmp eq i16 %iv.next, 1000
  br i1 %ec, label %exit, label %loop

exit:
  ret void
}