Bug type: crash
Component: LoopAccessAnalysis
Bug location: llvm/lib/Analysis/LoopAccessAnalysis.cpp: MemoryDepChecker::couldPreventStoreLoadForward
Issue title: [LoopVectorize] Assertion `isPowerOf2_32(End.getKnownMinValue()) && "Expected End to be a power of 2"' failed.
Labels: vectorizers
crash
generated by fuzzer
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"

@a = external global [0 x [12 x i16]]

define void @b(i64 %0) #0 {
entry:
  br label %for.cond3.preheader

for.cond3.preheader:                              ; preds = %for.cond3.preheader, %entry
  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.cond3.preheader ]
  %arrayidx9 = getelementptr [0 x [12 x i16]], ptr @a, i64 0, i64 0, i64 %indvars.iv
  %1 = load i16, ptr %arrayidx9, align 2
  %arrayidx9.2 = getelementptr [0 x [12 x i16]], ptr @a, i64 0, i64 8, i64 %indvars.iv
  store i16 0, ptr %arrayidx9.2, align 2
  %indvars.iv.next = add nsw i64 %indvars.iv, 3
  %cmp = icmp ult i64 %indvars.iv, %0
  br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup.loopexit

for.cond.cleanup.loopexit:                        ; preds = %for.cond3.preheader
  ret void
}

attributes #0 = { "target-features"="+v" }
```

Commands/backtrace
```
$ /scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt reduced.ll --passes=loop-vectorize
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/VPlanHelpers.h:87: llvm::VFRange::VFRange(const llvm::ElementCount&, const llvm::ElementCount&): Assertion `isPowerOf2_32(End.getKnownMinValue()) && "Expected End to be a power of 2"' 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 reduced.ll --passes=loop-vectorize
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 "b"
 #0 0x00005c0c5d95b1a2 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x349c1a2)
 #1 0x00005c0c5d95820f llvm::sys::RunSignalHandlers() (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x349920f)
 #2 0x00005c0c5d958354 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x0000774312045330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
 #4 0x000077431209eb2c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x000077431209eb2c __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x000077431209eb2c pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x000077431204527e raise ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007743120288ff abort ./stdlib/abort.c:81:7
 #9 0x000077431202881b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x000077431203b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#11 0x00005c0c5c7b1baf llvm::LoopVectorizationPlanner::buildVPlansWithVPRecipes(llvm::ElementCount, llvm::ElementCount) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x22f2baf)
#12 0x00005c0c5c7b210d llvm::LoopVectorizationPlanner::plan(llvm::ElementCount, unsigned int) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x22f310d)
#13 0x00005c0c5c7b4105 llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x22f5105)
#14 0x00005c0c5c7b7511 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x22f8511)
#15 0x00005c0c5c7b7ad7 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x22f8ad7)
#16 0x00005c0c5b484b75 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+0xfc5b75)
#17 0x00005c0c5d74633a 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+0x328733a)
#18 0x00005c0c5b4872b5 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+0xfc82b5)
#19 0x00005c0c5d744c14 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x3285c14)
#20 0x00005c0c5b483265 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+0xfc4265)
#21 0x00005c0c5d74522d 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+0x328622d)
#22 0x00005c0c5ac19391 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/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x75a391)
#23 0x00005c0c5ac0aeac optMain (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x74beac)
#24 0x000077431202a1ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#25 0x000077431202a28b call_init ./csu/../csu/libc-start.c:128:20
#26 0x000077431202a28b __libc_start_main ./csu/../csu/libc-start.c:347:5
#27 0x00005c0c5ac014f5 _start (/scratch/ewlu/daily-upstream-build/build-gcv/build-llvm-linux/bin/opt+0x7424f5)
Aborted (core dumped)
```

godbolt: https://godbolt.org/z/rKd5sx7xW

Found via fuzzer (C program before reduction)


Fix patch:
commit 995fd47944f471e985e34d7da8c0667059decbac
Author: Florian Hahn <flo@fhahn.com>
Date:   Sat Apr 12 20:05:37 2025 +0100

    [LAA] Make sure MaxVF for Store-Load forward safe dep distances is pow2.
    
    MaxVF computed in couldPreventStoreLoadFowrard may not be a power of 2,
    as CommonStride may not be a power-of-2.
    
    This can cause crashes after 78777a20. Use bit_floor to make sure it is
    a suitable power-of-2.
    
    Fixes https://github.com/llvm/llvm-project/issues/134696.

diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index a37ed5c706bd..0cb1332eb337 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -1781,7 +1781,8 @@ bool MemoryDepChecker::couldPreventStoreLoadForward(uint64_t Distance,
           MaxStoreLoadForwardSafeDistanceInBits &&
       MaxVFWithoutSLForwardIssuesPowerOf2 !=
           VectorizerParams::MaxVectorWidth * TypeByteSize) {
-    uint64_t MaxVF = MaxVFWithoutSLForwardIssuesPowerOf2 / CommonStride;
+    uint64_t MaxVF =
+        bit_floor(MaxVFWithoutSLForwardIssuesPowerOf2 / CommonStride);
     uint64_t MaxVFInBits = MaxVF * TypeByteSize * 8;
     MaxStoreLoadForwardSafeDistanceInBits =
         std::min(MaxStoreLoadForwardSafeDistanceInBits, MaxVFInBits);


Regression tests:
file: llvm/test/Transforms/LoopVectorize/RISCV/safe-dep-distance.ll
commands: opt < %s -passes=loop-vectorize -scalable-vectorization=on -riscv-v-vector-bits-min=-1 -mtriple riscv64-linux-gnu -mattr=+v,+f -S
tests: test_name: safe_load_store_distance_not_pow_of_2
test_body: target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
target triple = "riscv64"

@a = external global [10 x [12 x i16]]

define void @safe_load_store_distance_not_pow_of_2(i64 %N) {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %gep = getelementptr [10 x [12 x i16]], ptr @a, i64 0, i64 0, i64 %iv
  %0 = load i16, ptr %gep, align 2
  %gep.off = getelementptr [10 x [12 x i16]], ptr @a, i64 0, i64 8, i64 %iv
  store i16 0, ptr %gep.off, align 2
  %iv.next = add nsw i64 %iv, 3
  %cmp = icmp ult i64 %iv, %N
  br i1 %cmp, label %loop, label %exit

exit:                                             ; preds = %loop
  ret void
}