Bug type: crash
Component: LoopVectorize
Bug location: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp: LoopVectorizationPlanner::precomputeCosts
Issue title: [VPlan] Assertion " VPlan cost model and legacy cost model disagreed"' failed.
Labels: vectorizers
crash
Reported by: patrick-rivos

Tested using 190449a5d2a9ddfc2180dce11714a4443f0f29f0

Testcase:
```c
char a;
extern short b[][6][6];
short c;
long d;
long *e, *f;
void g(char h[][6]) {
  for (short i = d + 9; i < 4; i += 3) {
    a = ({ f[i]; }) < f[i - 1];
    for (int j = c; j; j = ({ h[5][i + 2]; }) ? e[i - 1] : 0)
      ;
    b[i][i][i] = 0;
  }
}
```
https://godbolt.org/z/EGdEPbKad

IR testcase:
```llvm ir
; ModuleID = 'reduced.bc'
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"

define void @g(i16 %0, i64 %indvars.iv52) #0 {
entry:
  %conv146 = sext i16 %0 to i32
  %1 = sext i16 %0 to i64
  %invariant.gep = getelementptr i8, ptr null, i64 -8
  br label %for.body.us

for.body.us:                                      ; preds = %for.body.us, %entry
  %indvars.iv521 = phi i64 [ %1, %entry ], [ %indvars.iv.next53, %for.body.us ]
  %conv149.us = phi i32 [ %conv146, %entry ], [ %5, %for.body.us ]
  %arrayidx.us = getelementptr i64, ptr null, i64 %indvars.iv521
  %2 = load i64, ptr %arrayidx.us, align 8
  %3 = sext i32 %conv149.us to i64
  %gep = getelementptr i64, ptr %invariant.gep, i64 %3
  %4 = load i64, ptr %gep, align 8
  %arrayidx31.us = getelementptr [0 x [6 x [6 x i16]]], ptr null, i64 0, i64 %indvars.iv521, i64 %indvars.iv52, i64 %indvars.iv52
  store i16 0, ptr %arrayidx31.us, align 2
  %indvars.iv.next53 = add i64 %indvars.iv521, 3
  %5 = trunc i64 %indvars.iv.next53 to i32
  %cmp.us = icmp slt i64 %indvars.iv521, 0
  br i1 %cmp.us, label %for.body.us, label %for.cond.for.cond.cleanup_crit_edge.split.us

for.cond.for.cond.cleanup_crit_edge.split.us:     ; preds = %for.body.us
  ret void
}

attributes #0 = { "target-features"="+64bit,+a,+c,+d,+f,+m,+relax,+v,+zicsr,+zifencei,+zmmul,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl256b,+zvl32b,+zvl64b,-b,-e,-experimental-smctr,-experimental-smmpm,-experimental-smnpm,-experimental-ssctr,-experimental-ssnpm,-experimental-sspm,-experimental-supm,-experimental-zacas,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-experimental-zvbc32e,-experimental-zvkgs,-h,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smepmp,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssqosid,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl16384b,-zvl2048b,-zvl32768b,-zvl4096b,-zvl512b,-zvl65536b,-zvl8192b" }
```

Command/backtrace:
```
> /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt -passes=loop-vectorize -S reduced.ll
opt: /scratch/tc-testing/tc-compiler-fuzz-trunk/llvm/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:7359: llvm::VectorizationFactor llvm::LoopVectorizationPlanner::computeBestVF(): Assertion `(BestFactor.Width == LegacyVF.Width || planContainsAdditionalSimplifications(getPlanFor(BestFactor.Width), BestFactor.Width, CostCtx, OrigLoop, CM)) && " VPlan cost model and legacy cost model disagreed"' 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/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt -passes=loop-vectorize -S reduced.ll
1.      Running pass "function(loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>)" on module "reduced.ll"
2.      Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "g"
 #0 0x0000640a195798f0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x30178f0)
 #1 0x0000640a19576d0f llvm::sys::RunSignalHandlers() (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x3014d0f)
 #2 0x0000640a19576e65 SignalHandler(int) Signals.cpp:0:0
 #3 0x00007aac19442520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007aac194969fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007aac194969fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007aac194969fc pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x00007aac19442476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007aac194287f3 abort ./stdlib/abort.c:81:7
 #9 0x00007aac1942871b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007aac19439e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#11 0x0000640a18546ac9 llvm::LoopVectorizationPlanner::computeBestVF() (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x1fe4ac9)
#12 0x0000640a1855cedb llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x1ffaedb)
#13 0x0000640a1855fef1 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x1ffdef1)
#14 0x0000640a18560567 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x1ffe567)
#15 0x0000640a173c0a96 llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0xe5ea96)
#16 0x0000640a19384d4f llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x2e22d4f)
#17 0x0000640a173c3c26 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/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0xe61c26)
#18 0x0000640a19383acb llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x2e21acb)
#19 0x0000640a173bfec6 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0xe5dec6)
#20 0x0000640a19381b0d llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x2e1fb0d)
#21 0x0000640a16be9da6 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) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x687da6)
#22 0x0000640a16bdbb31 optMain (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x679b31)
#23 0x00007aac19429d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#24 0x00007aac19429e40 call_init ./csu/../csu/libc-start.c:128:20
#25 0x00007aac19429e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#26 0x0000640a16bd1ee5 _start (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x66fee5)
zsh: IOT instruction (core dumped)  /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt
```
https://godbolt.org/z/W3KqbcKrb

Found via fuzzer
Related/prior issue: #104714

cc @fhahn 


Fix patch:
commit c4906588ce47de33d59bcd95f3e82ce2c3e61c23
Author: Florian Hahn <flo@fhahn.com>
Date:   Thu Aug 29 21:19:59 2024 +0100

    [VPlan] Use skipCostComputation when pre-computing induction costs.
    
    This ensures we skip any instructions identified to be ignored by the
    legacy cost model as well. Fixes a divergence between legacy and
    VPlan-based cost model.
    
    Fixes https://github.com/llvm/llvm-project/issues/106417.

diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 4cc75e2e7546..6babfd1eee91 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -7113,7 +7113,7 @@ LoopVectorizationPlanner::precomputeCosts(VPlan &Plan, ElementCount VF,
       IVInsts.push_back(CI);
     }
     for (Instruction *IVInst : IVInsts) {
-      if (!CostCtx.SkipCostComputation.insert(IVInst).second)
+      if (CostCtx.skipCostComputation(IVInst, VF.isVector()))
         continue;
       InstructionCost InductionCost = CostCtx.getLegacyCost(IVInst, VF);
       LLVM_DEBUG({
@@ -7121,6 +7121,7 @@ LoopVectorizationPlanner::precomputeCosts(VPlan &Plan, ElementCount VF,
                << ": induction instruction " << *IVInst << "\n";
       });
       Cost += InductionCost;
+      CostCtx.SkipCostComputation.insert(IVInst);
     }
   }
 


Regression tests:
file: llvm/test/Transforms/LoopVectorize/RISCV/induction-costs.ll
commands: opt -p loop-vectorize -S %s
tests: test_name: skip_free_iv_truncate
test_body: target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"

define void @skip_free_iv_truncate(i16 %x, ptr %A) #0 {
entry:
  %x.i32 = sext i16 %x to i32
  %x.i64 = sext i16 %x to i64
  %invariant.gep = getelementptr i8, ptr %A, i64 -8
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i64 [ %x.i64, %entry ], [ %iv.next, %loop ]
  %iv.conv = phi i32 [ %x.i32, %entry ], [ %3, %loop ]
  %gep.i64 = getelementptr i64, ptr %A, i64 %iv
  %0 = load i64, ptr %gep.i64, align 8
  %1 = sext i32 %iv.conv to i64
  %gep.conv = getelementptr i64, ptr %invariant.gep, i64 %1
  %2 = load i64, ptr %gep.conv, align 8
  %gep.i16 = getelementptr i16, ptr %A, i64 %iv
  store i16 0, ptr %gep.i16, align 2
  %iv.next = add i64 %iv, 3
  %3 = trunc i64 %iv.next to i32
  %c = icmp slt i64 %iv, 99
  br i1 %c, label %loop, label %exit

exit:                                             ; preds = %loop
  ret void
}

attributes #0 = { "target-features"="+64bit,+v,+zvl256b" }