Bug type: crash
Component: LoopVectorize
Bug location: llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp: UnrollState::unrollWidenInductionByUF
Issue title: Assertion `getActiveBits() <= 64 && "Too many bits for uint64_t"' failed.
Labels: vectorizers
crash
Reported by: TatyanaDoubts

To reproduce run the test below with -passes=loop-vectorize
```
; ModuleID = './reduced.ll'
source_filename = "./reduced.ll"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32-ni:1-p2:32:8:8:32-ni:2"
target triple = "aarch64-none-linux-gnu"

define double @wombat() gc "statepoint-example" {
bb:
  br label %bb2

bb1:                                              ; preds = %bb2
  ret double 0.000000e+00

bb2:                                              ; preds = %bb2, %bb
  %phi = phi i64 [ 0, %bb ], [ %add, %bb2 ]
  %phi3 = phi i65 [ 0, %bb ], [ %add5, %bb2 ]
  %phi4 = phi i64 [ 0, %bb ], [ %trunc, %bb2 ]
  %trunc = trunc i65 %phi3 to i64
  store i64 0, ptr addrspace(1) null, align 8
  %add = add i64 %phi, 1
  %icmp = icmp ugt i64 %add, 0
  %add5 = add i65 %phi3, -1
  br i1 %icmp, label %bb2, label %bb1
}
```
Reproducer: https://godbolt.org/z/cjEcv8b4Y

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 "wombat"
 #0 0x00000000051b3748 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x51b3748)
 #1 0x00000000051b113c SignalHandler(int) Signals.cpp:0:0
 #2 0x000071a06ec42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x000071a06ec969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x000071a06ec42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x000071a06ec287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x000071a06ec2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #7 0x000071a06ec39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #8 0x0000000000b2d8a9 (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xb2d8a9)
 #9 0x0000000004308ae6 (anonymous namespace)::UnrollState::unrollBlock(llvm::VPBlockBase*) VPlanUnroll.cpp:0:0
#10 0x000000000430788c (anonymous namespace)::UnrollState::unrollBlock(llvm::VPBlockBase*) VPlanUnroll.cpp:0:0
#11 0x0000000004309060 llvm::VPlanTransforms::unrollByUF(llvm::VPlan&, unsigned int, llvm::LLVMContext&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4309060)
#12 0x0000000004176b76 llvm::LoopVectorizationPlanner::executePlan(llvm::ElementCount, unsigned int, llvm::VPlan&, llvm::InnerLoopVectorizer&, llvm::DominatorTree*, bool, llvm::DenseMap<llvm::SCEV const*, llvm::Value*, llvm::DenseMapInfo<llvm::SCEV const*, void>, llvm::detail::DenseMapPair<llvm::SCEV const*, llvm::Value*>> const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4176b76)
#13 0x000000000418cb6f llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x418cb6f)
#14 0x000000000418ebd9 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x418ebd9)
#15 0x000000000418f213 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x418f213)
#16 0x0000000002fcba8e 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+0x2fcba8e)
#17 0x0000000004fb2700 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4fb2700)
#18 0x0000000000e33a9e 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+0xe33a9e)
#19 0x0000000004fb101b llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4fb101b)
#20 0x0000000000e3312e 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+0xe3312e)
#21 0x0000000004fb0a20 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4fb0a20)
#22 0x0000000000910a1a 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) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x910a1a)
#23 0x0000000000903099 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x903099)
#24 0x000071a06ec29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#25 0x000071a06ec29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#26 0x00000000008fa97e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8fa97e)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```


Comments: author: huang-me
body: Hi @TatyanaDoubts, 
How did you get the IR snippet? 
The IR you provided is weird. I'll have to check where i65 constant 0 in `%phi3 = phi i65 [ 0, %bb ], [ %add5, %bb2 ]` come from since it seems it's the origin of the problem.
author: fhahn
body: I suspect this was found via a fuzzer, thanks for sharing the test case!
author: TatyanaDoubts
body: Hi @huang-me, @fhahn, yes this crash was found by the fuzzer generated test.  

Fix patch:
commit 4f7f71b7bccdc38f37b82981e8fa9ceb536a7016
Author: Florian Hahn <flo@fhahn.com>
Date:   Fri Dec 6 16:28:47 2024 +0000

    [VPlan] Compare APInt instead of getSExtValue to fix crash in unroll.
    
    getSExtValue assumes the result fits in 64 bits, but this may not be the
    case for indcutions with wider types. Instead, directly perform the
    compare on the APInt for the ConstantInt.
    
    Fixes https://github.com/llvm/llvm-project/issues/118850.

diff --git a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
index f653269713b3..ff6c9295ee20 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
@@ -168,7 +168,7 @@ void UnrollState::unrollWidenInductionByUF(
   auto *ConstStep = ScalarStep->isLiveIn()
                         ? dyn_cast<ConstantInt>(ScalarStep->getLiveInIRValue())
                         : nullptr;
-  if (!ConstStep || ConstStep->getZExtValue() != 1) {
+  if (!ConstStep || ConstStep->getValue() != 1) {
     if (TypeInfo.inferScalarType(ScalarStep) != IVTy) {
       ScalarStep =
           Builder.createWidenCast(Instruction::Trunc, ScalarStep, IVTy);


Regression tests:
file: llvm/test/Transforms/LoopVectorize/interleave-with-i65-induction.ll
commands: opt -p loop-vectorize -force-vector-width=4 -force-vector-interleave=2 -S %s
tests: test_name: i65_induction_with_negative_step
test_body: define void @i65_induction_with_negative_step(ptr %dst) {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %iv.i65 = phi i65 [ 0, %entry ], [ %iv.i65.next, %loop ]
  %for = phi i64 [ 0, %entry ], [ %trunc, %loop ]
  %trunc = trunc i65 %iv.i65 to i64
  %gep = getelementptr inbounds i64, ptr %dst, i64 %trunc
  store i64 %for, ptr %gep, align 8
  %iv.next = add i64 %iv, 1
  %icmp = icmp eq i64 %iv.next, 1000
  %iv.i65.next = add i65 %iv.i65, -1
  br i1 %icmp, label %exit, label %loop

exit:                                             ; preds = %loop
  ret void
}