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);

opt -p loop-vectorize -force-vector-width=4 -force-vector-interleave=2 -S %s

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
}

Assertion `getActiveBits() <= 64 && "Too many bits for uint64_t"' failed.

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
```

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.

I suspect this was found via a fuzzer, thanks for sharing the test case!

Hi @huang-me, @fhahn, yes this crash was found by the fuzzer generated test.


commit 958e37cd1feabf29fb1cc3fb5ac82051ad8d43eb
Author: Simon Pilgrim <llvm-dev@redking.me.uk>
Date:   Sat Nov 9 15:59:52 2024 +0000

    [VectorCombine] scalarizeBinopOrCmp - check for out of bounds element indices

    Fixes #115575

diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 04ea12ef0f12..b8754b03c2eb 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -952,6 +952,12 @@ bool VectorCombine::scalarizeBinopOrCmp(Instruction &I) {
   if (!IsConst0 && !IsConst1 && Index0 != Index1)
     return false;

+  auto *VecTy0 = cast<VectorType>(Ins0->getType());
+  auto *VecTy1 = cast<VectorType>(Ins1->getType());
+  if (VecTy0->getElementCount().getKnownMinValue() <= Index0 ||
+      VecTy1->getElementCount().getKnownMinValue() <= Index1)
+    return false;
+
   // Bail for single insertion if it is a load.
   // TODO: Handle this once getVectorInstrCost can cost for load/stores.
   auto *I0 = dyn_cast_or_null<Instruction>(V0);

opt < %s -passes=vector-combine -S -mtriple=x86_64--

define <2 x i8> @PR115575(i8 %x) {
  %ins = insertelement <2 x i8> poison, i8 %x, i32 3
  %bo = sdiv <2 x i8> %ins, <i8 5, i8 2>
  ret <2 x i8> %bo
}

[VectorCombine] UB triggered after optimization

https://github.com/llvm/llvm-project/blob/c93e001ca695e905cb965b36d63f7a348d1dd809/llvm/lib/Transforms/Vectorize/VectorCombine.cpp#L1013-L1031

Alive2 report: https://alive2.llvm.org/ce/z/78CM4x

```llvm
----------------------------------------
define <2 x i8> @sdiv_constant_op1_not_undef_lane.2(i8 %x) {
#0:
  %ins = insertelement <2 x i8> poison, i8 %x, i32 3
  %bo = sdiv <2 x i8> %ins, { 5, 2 }
  ret <2 x i8> %bo
}
=>
define <2 x i8> @sdiv_constant_op1_not_undef_lane.2(i8 %x) {
#0:
  %bo.scalar = sdiv i8 %x, poison
  %bo = insertelement <2 x i8> poison, i8 %bo.scalar, i64 3
  ret <2 x i8> %bo
}
Transformation doesn't verify!

ERROR: Source is more defined than target

Example:
i8 %x = poison

Source:
<2 x i8> %ins = < poison, poison >
<2 x i8> %bo = < poison, poison >

Target:
i8 %bo.scalar = UB triggered!

----------------------------------------
define <2 x i64> @urem_constant_op1_not_undef_lane.2(i64 %x) {
#0:
  %ins = insertelement <2 x i64> poison, i64 %x, i32 4294967295
  %bo = urem <2 x i64> %ins, { 5, 2 }
  ret <2 x i64> %bo
}
=>
define <2 x i64> @urem_constant_op1_not_undef_lane.2(i64 %x) {
#0:
  %bo.scalar = urem i64 %x, poison
  %bo = insertelement <2 x i64> poison, i64 %bo.scalar, i64 4294967295
  ret <2 x i64> %bo
}
Transformation doesn't verify!

ERROR: Source is more defined than target

Example:
i64 %x = poison

Source:
<2 x i64> %ins = < poison, poison >
<2 x i64> %bo = < poison, poison >

Target:
i64 %bo.scalar = UB triggered!

Summary:
  0 correct transformations
  2 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors
```


commit 77bec78878762e34150fe23734fa43df796c873c
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Fri Nov 8 04:16:01 2024 -0800

    [SLP]Do not look for last instruction in schedule block for buildvectors

    If looking for the insertion point for the node and the node is
    a buildvector node, the compiler should not use scheduling info for such
    nodes, they may contain only partial info, which is not fully correct
    and may cause compiler crash.

    Fixes #114082

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index b2f677fb84f9..c5b3537bc57b 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -13398,7 +13398,7 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
   // scheduled, and the last instruction is VL.back(). So we start with
   // VL.back() and iterate over schedule data until we reach the end of the
   // bundle. The end of the bundle is marked by null ScheduleData.
-  if (BlocksSchedules.count(BB)) {
+  if (BlocksSchedules.count(BB) && !E->isGather()) {
     Value *V = E->isOneOf(E->Scalars.back());
     if (doesNotNeedToBeScheduled(V))
       V = *find_if_not(E->Scalars, doesNotNeedToBeScheduled);

opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-threshold=-99999 < %s

define void @test() {
bb:
  %icmp = icmp samesign ult i32 0, 0
  %select = select i1 %icmp, i32 0, i32 0
  %zext = zext i32 %select to i64
  %getelementptr = getelementptr ptr addrspace(1), ptr addrspace(1) null, i64 %zext
  store ptr addrspace(1) null, ptr addrspace(1) %getelementptr, align 8
  %icmp1 = icmp eq i32 0, 0
  %icmp2 = icmp eq i32 0, 0
  %icmp3 = icmp samesign ult i32 0, 0
  %icmp4 = icmp eq i32 0, 0
  %add = add i32 1, 0
  %icmp5 = icmp samesign ult i32 %add, 0
  store volatile i32 0, ptr addrspace(1) null, align 4
  %call = call i32 null(<2 x double> zeroinitializer)
  %icmp6 = icmp eq i32 %call, 0
  %icmp7 = icmp samesign ult i32 0, 0
  ret void
}

[SLPVectorizer] Instruction does not dominate all uses! LLVM ERROR: Broken module found, compilation aborted!

To reproduce run opt with the test below with -passes=slp-vectorizer -slp-threshold=-99999
```; ModuleID = './reduced.ll'
source_filename = "./reduced.ll"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"
target triple = "x86_64-unknown-linux-gnu"

define void @wombat() #0 gc "statepoint-example" {
bb:
  %icmp = icmp samesign ult i32 0, 0
  %select = select i1 %icmp, i32 0, i32 0
  %zext = zext i32 %select to i64
  %getelementptr = getelementptr ptr addrspace(1), ptr addrspace(1) null, i64 %zext
  store ptr addrspace(1) null, ptr addrspace(1) %getelementptr, align 8
  %icmp1 = icmp eq i32 0, 0
  %icmp2 = icmp eq i32 0, 0
  %icmp3 = icmp samesign ult i32 0, 0
  %icmp4 = icmp eq i32 0, 0
  %add = add i32 1, 0
  %icmp5 = icmp samesign ult i32 %add, 0
  store volatile i32 0, ptr addrspace(1) null, align 4
  %call = call i32 @llvm.x86.sse2.cvttsd2si(<2 x double> zeroinitializer)
  %icmp6 = icmp eq i32 %call, 0
  %icmp7 = icmp samesign ult i32 0, 0
  ret void
}

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
declare i32 @llvm.x86.sse2.cvttsd2si(<2 x double>) #1

attributes #0 = { "target-features"="+prfchw,-cldemote,+avx,+aes,+sahf,+pclmul,-xop,+crc32,+xsaves,-avx512fp16,-usermsr,-sm4,-egpr,+sse4.1,-avx512ifma,+xsave,+sse4.2,-tsxldtrk,-sm3,-ptwrite,-widekl,+invpcid,+64bit,+xsavec,-avx10.1-512,-avx512vpopcntdq,+cmov,-avx512vp2intersect,+avx512cd,+movbe,-avxvnniint8,-ccmp,-amx-int8,-kl,-avx10.1-256,+evex512,-avxvnni,+rtm,+adx,+avx2,-hreset,-movdiri,-serialize,-sha512,-vpclmulqdq,+avx512vl,-uintr,-cf,+clflushopt,-raoint,-cmpccxadd,+bmi,-amx-tile,+sse,-avx10.2-256,-gfni,-avxvnniint16,-amx-fp16,-zu,-ndd,+xsaveopt,+rdrnd,+avx512f,-amx-bf16,-avx512bf16,-avx512vnni,-push2pop2,+cx8,+avx512bw,+sse3,+pku,-nf,+fsgsbase,-clzero,-mwaitx,-lwp,+lzcnt,-sha,-movdir64b,-ppx,-wbnoinvd,-enqcmd,-avx10.2-512,-avxneconvert,-tbm,-pconfig,-amx-complex,+ssse3,+cx16,+bmi2,+fma,+popcnt,-avxifma,+f16c,-avx512bitalg,-rdpru,+clwb,+mmx,+sse2,+rdseed,-avx512vbmi2,-prefetchi,-rdpid,-fma4,-avx512vbmi,-shstk,-vaes,-waitpkg,-sgx,+fxsr,+avx512dq,-sse4a,-avx512f" }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(none) "target-features"="+prfchw,-cldemote,+avx,+aes,+sahf,+pclmul,-xop,+crc32,+xsaves,-avx512fp16,-usermsr,-sm4,-egpr,+sse4.1,-avx512ifma,+xsave,+sse4.2,-tsxldtrk,-sm3,-ptwrite,-widekl,+invpcid,+64bit,+xsavec,-avx10.1-512,-avx512vpopcntdq,+cmov,-avx512vp2intersect,+avx512cd,+movbe,-avxvnniint8,-ccmp,-amx-int8,-kl,-avx10.1-256,+evex512,-avxvnni,+rtm,+adx,+avx2,-hreset,-movdiri,-serialize,-sha512,-vpclmulqdq,+avx512vl,-uintr,-cf,+clflushopt,-raoint,-cmpccxadd,+bmi,-amx-tile,+sse,-avx10.2-256,-gfni,-avxvnniint16,-amx-fp16,-zu,-ndd,+xsaveopt,+rdrnd,+avx512f,-amx-bf16,-avx512bf16,-avx512vnni,-push2pop2,+cx8,+avx512bw,+sse3,+pku,-nf,+fsgsbase,-clzero,-mwaitx,-lwp,+lzcnt,-sha,-movdir64b,-ppx,-wbnoinvd,-enqcmd,-avx10.2-512,-avxneconvert,-tbm,-pconfig,-amx-complex,+ssse3,+cx16,+bmi2,+fma,+popcnt,-avxifma,+f16c,-avx512bitalg,-rdpru,+clwb,+mmx,+sse2,+rdseed,-avx512vbmi2,-prefetchi,-rdpid,-fma4,-avx512vbmi,-shstk,-vaes,-waitpkg,-sgx,+fxsr,+avx512dq,-sse4a,-avx512f" }
```
Reproducer: https://godbolt.org/z/nTE84xq7n

Stack dump
```
Instruction does not dominate all uses!
  %5 = icmp eq <4 x i32> %4, zeroinitializer
  %2 = call <8 x i1> @llvm.vector.insert.v8i1.v4i1(<8 x i1> poison, <4 x i1> %5, i64 0)
LLVM ERROR: Broken module found, compilation aborted!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/opt -o /app/output.s -S -passes=slp-vectorizer -slp-threshold=-99999 <source>
1.	Running pass "verify" on module "<source>"
 #0 0x00000000050e7a98 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x50e7a98)
 #1 0x00000000050e548c SignalHandler(int) Signals.cpp:0:0
 #2 0x000078c8a0042520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x000078c8a00969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x000078c8a0042476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x000078c8a00287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x00000000007d7d7b llvm::json::operator==(llvm::json::Value const&, llvm::json::Value const&) (.cold) JSON.cpp:0:0
 #7 0x00000000050265b8 (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x50265b8)
 #8 0x0000000004f24790 llvm::VerifierPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4f24790)
 #9 0x00000000009015ce llvm::detail::PassModel<llvm::Module, llvm::VerifierPass, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x9015ce)
#10 0x0000000004ee5440 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4ee5440)
#11 0x000000000090c1ea 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+0x90c1ea)
#12 0x00000000008ff258 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8ff258)
#13 0x000078c8a0029d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#14 0x000078c8a0029e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#15 0x00000000008f6d2e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8f6d2e)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```


commit 899336735aeb2b41a48b6ac2c895da5e0f22dbf0
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Mon Nov 4 06:02:06 2024 -0800

    [SLP]Be more pessimistic about poisonous reductions

    Consider all possible reductions ops as being non-poisoning boolean
    logical operations, which require freeze to be fully correct.

    https://alive2.llvm.org/ce/z/TKWDMP

    Fixes #114738

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 427b8bd0e75a..3c6daf7b9fbb 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -19490,9 +19490,7 @@ public:
         // To prevent poison from leaking across what used to be sequential,
         // safe, scalar boolean logic operations, the reduction operand must be
         // frozen.
-        if ((isBoolLogicOp(RdxRootInst) ||
-             (AnyBoolLogicOp && VL.size() != TrackedVals.size())) &&
-            !isGuaranteedNotToBePoison(VectorizedRoot))
+        if (AnyBoolLogicOp && !isGuaranteedNotToBePoison(VectorizedRoot))
           VectorizedRoot = Builder.CreateFreeze(VectorizedRoot);

         // Emit code to correctly handle reused reduced values, if required.

define i1 @test(i32 %x, i32 %a, i32 %b, i32 %c, i32 %d) {
  %cmp = icmp sgt i32 %x, 1
  %cmp2 = icmp sgt i32 %b, 1
  %cmp3 = icmp sgt i32 %c, 1
  %cmp4 = icmp sgt i32 %d, 1
  %sel2 = select i1 %cmp4, i1 true, i1 %cmp2
  %sel3 = select i1 %sel2, i1 true, i1 %cmp3
  %sel4 = select i1 %cmp, i1 true, i1 %cmp4
  %ret = or i1 %sel3, %sel4
  ret i1 %ret
}

[SLPVectorizer] wrong vectorization to `reduce_or` due to poisonous value

Alive2 report: https://alive2.llvm.org/ce/z/f8PDZj

```llvm
----------------------------------------
define i1 @test1.2(i32 %x, i32 %a, i32 %b, i32 %c, i32 %d) {
#0:
  %cmp = icmp sgt i32 %x, 1
  %cmp2 = icmp sgt i32 %b, 1
  %cmp3 = icmp sgt i32 %c, 1
  %cmp4 = icmp sgt i32 %d, 1
  %sel2 = select i1 %cmp4, i1 1, i1 %cmp2
  %sel3 = select i1 %sel2, i1 1, i1 %cmp3
  %sel4 = select i1 %cmp, i1 1, i1 %cmp4
  %ret = or i1 %sel3, %sel4
  ret i1 %ret
}
=>
define i1 @test1.2(i32 %x, i32 %a, i32 %b, i32 %c, i32 %d) {
#0:
  %#1 = insertelement <4 x i32> poison, i32 %d, i32 0
  %#2 = insertelement <4 x i32> %#1, i32 %b, i32 1
  %#3 = insertelement <4 x i32> %#2, i32 %c, i32 2
  %#4 = insertelement <4 x i32> %#3, i32 %x, i32 3
  %#5 = icmp sgt <4 x i32> %#4, { 1, 1, 1, 1 }
  %#6 = reduce_or <4 x i1> %#5
  ret i1 %#6
}
Transformation doesn't verify!

ERROR: Target is more poisonous than source

Example:
i32 %x = #x00000000 (0)
i32 %a = poison
i32 %b = #x00000002 (2)
i32 %c = poison
i32 %d = #x00000000 (0)

Source:
i1 %cmp = #x0 (0)
i1 %cmp2 = #x1 (1)
i1 %cmp3 = poison
i1 %cmp4 = #x0 (0)
i1 %sel2 = #x1 (1)
i1 %sel3 = #x1 (1)
i1 %sel4 = #x0 (0)
i1 %ret = #x1 (1)

Target:
<4 x i32> %#1 = < #x00000000 (0), poison, poison, poison >
<4 x i32> %#2 = < #x00000000 (0), #x00000002 (2), poison, poison >
<4 x i32> %#3 = < #x00000000 (0), #x00000002 (2), poison, poison >
<4 x i32> %#4 = < #x00000000 (0), #x00000002 (2), poison, #x00000000 (0) >
<4 x i1> %#5 = < #x0 (0), #x1 (1), poison, #x0 (0) >
i1 %#6 = poison
Source value: #x1 (1)
Target value: poison

Summary:
  0 correct transformations
  1 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors
```


commit 50a02e7c68f964c5d8338369746c849ed8d3bef4
Author: Florian Hahn <flo@fhahn.com>
Date:   Mon Sep 2 20:47:36 2024 +0100

    [VPlan] Pass intrinsic inst to TTI in VPWidenCallRecipe::computeCost.

    Follow-up to 9ccf825, adjust computeCost to also pass IntrinsicInst to
    TTI if available, as there are multiple places in TTI which use the
    IntrinsicInst.

    Fixes https://github.com/llvm/llvm-project/issues/107016.

diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index e782ac444d02..c91ea2d1663c 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -965,8 +965,10 @@ InstructionCost VPWidenCallRecipe::computeCost(ElementCount VF,
     ParamTys.push_back(
         ToVectorTy(Ctx.Types.inferScalarType(getOperand(I)), VF));

-  IntrinsicCostAttributes CostAttrs(VectorIntrinsicID, RetTy, Arguments,
-                                    ParamTys, FMF);
+  // TODO: Rework TTI interface to avoid reliance on underlying IntrinsicInst.
+  IntrinsicCostAttributes CostAttrs(
+      VectorIntrinsicID, RetTy, Arguments, ParamTys, FMF,
+      dyn_cast_or_null<IntrinsicInst>(getUnderlyingValue()));
   return Ctx.TTI.getIntrinsicInstrCost(CostAttrs, CostKind);
 }

target triple = "arm64-apple-macosx11.0.0"

define void @fshl_operand_first_order_recurrence(ptr %dst, ptr noalias %src) {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %recur = phi i64 [ 0, %entry ], [ %l, %loop ]
  %gep.src = getelementptr inbounds i64, ptr %src, i64 %iv
  %l = load i64, ptr %gep.src, align 8
  %or = tail call i64 @llvm.fshl.i64(i64 1, i64 %recur, i64 1)
  %gep.dst = getelementptr inbounds i64, ptr %dst, i64 %iv
  store i64 %or, ptr %gep.dst, align 8
  %iv.next = add i64 %iv, 1
  %exitcond.not = icmp eq i64 %iv, 100
  br i1 %exitcond.not, label %exit, label %loop

exit:                                             ; preds = %loop
  ret void
}

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

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

target triple = "arm64-apple-macosx11.0.0"

define void @powi_call(ptr %P) {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %gep = getelementptr inbounds double, ptr %P, i64 %iv
  %l = load double, ptr %gep, align 8
  %powi = tail call double @llvm.powi.f64.i32(double %l, i32 3)
  store double %powi, ptr %gep, align 8
  %iv.next = add i64 %iv, 1
  %ec = icmp eq i64 %iv, 1
  br i1 %ec, label %exit, label %loop

exit:                                             ; preds = %loop
  ret void
}

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

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

[VPlan] clang crash

Failure since https://github.com/llvm/llvm-project/pull/106047

[repro.zip](https://github.com/user-attachments/files/16840758/repro.zip)

```
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /scratch3/packages/llvm/main-20240902/bin/clang-20 -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -disable-free -clear-ast-before-backend -main-file-name PairCorrEstimator.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -menable-no-infs -menable-no-nans -fapprox-func -funsafe-math-optimizations -fno-signed-zeros -mreassociate -freciprocal-math -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -complex-range=basic -mconstructor-aliases -funwind-tables=2 -target-cpu skylake-avx512 -target-feature +prfchw -target-feature -cldemote -target-feature +avx -target-feature +aes -target-feature +sahf -target-feature +pclmul -target-feature -xop -target-feature +crc32 -target-feature +xsaves -target-feature -avx512fp16 -target-feature -usermsr -target-feature -sm4 -target-feature -egpr -target-feature +sse4.1 -target-feature -avx512ifma -target-feature +xsave -target-feature +sse4.2 -target-feature -tsxldtrk -target-feature -sm3 -target-feature -ptwrite -target-feature -widekl -target-feature +invpcid -target-feature +64bit -target-feature +xsavec -target-feature -avx10.1-512 -target-feature -avx512vpopcntdq -target-feature +cmov -target-feature -avx512vp2intersect -target-feature +avx512cd -target-feature +movbe -target-feature -avxvnniint8 -target-feature -ccmp -target-feature -amx-int8 -target-feature -kl -target-feature -avx10.1-256 -target-feature +evex512 -target-feature -avxvnni -target-feature +rtm -target-feature +adx -target-feature +avx2 -target-feature -hreset -target-feature -movdiri -target-feature -serialize -target-feature -sha512 -target-feature -vpclmulqdq -target-feature +avx512vl -target-feature -uintr -target-feature -cf -target-feature +clflushopt -target-feature -raoint -target-feature -cmpccxadd -target-feature +bmi -target-feature -amx-tile -target-feature +sse -target-feature -avx10.2-256 -target-feature -gfni -target-feature -avxvnniint16 -target-feature -amx-fp16 -target-feature -zu -target-feature -ndd -target-feature +xsaveopt -target-feature +rdrnd -target-feature +avx512f -target-feature -amx-bf16 -target-feature -avx512bf16 -target-feature -avx512vnni -target-feature -push2pop2 -target-feature +cx8 -target-feature +avx512bw -target-feature +sse3 -target-feature +pku -target-feature -nf -target-feature +fsgsbase -target-feature -clzero -target-feature -mwaitx -target-feature -lwp -target-feature +lzcnt -target-feature -sha -target-feature -movdir64b -target-feature -ppx -target-feature -wbnoinvd -target-feature -enqcmd -target-feature -avx10.2-512 -target-feature -avxneconvert -target-feature -tbm -target-feature -pconfig -target-feature -amx-complex -target-feature +ssse3 -target-feature +cx16 -target-feature +bmi2 -target-feature +fma -target-feature +popcnt -target-feature -avxifma -target-feature +f16c -target-feature -avx512bitalg -target-feature -rdpru -target-feature +clwb -target-feature +mmx -target-feature +sse2 -target-feature +rdseed -target-feature -avx512vbmi2 -target-feature -prefetchi -target-feature -rdpid -target-feature -fma4 -target-feature -avx512vbmi -target-feature -shstk -target-feature -vaes -target-feature -waitpkg -target-feature -sgx -target-feature +fxsr -target-feature +avx512dq -target-feature -sse4a -debugger-tuning=gdb -fdebug-compilation-dir=/scratch3/opt/qmcpack/build_clangPatched_real/src/QMCHamiltonians -fcoverage-compilation-dir=/scratch3/opt/qmcpack/build_clangPatched_real/src/QMCHamiltonians -sys-header-deps -D ADD_ -D H5_USE_110_API -D HAVE_CONFIG_H -D HAVE_EINSPLINE -D HAVE_LIBBOOST -D HAVE_LIBFFTW -D HAVE_MKL -D HAVE_MKL_VML -D MPICH_SKIP_MPICXX -D OMPI_SKIP_MPICXX -D OPENMP_NO_COMPLEX -D _MPICC_H -D restrict=__restrict__ -D NDEBUG -O3 -Wvla -Wall -Wno-unused-variable -Wno-overloaded-virtual -Wno-unused-private-field -Wno-unused-local-typedef -Wsuggest-override -Wno-unknown-pragmas -Wmisleading-indentation -std=c++17 -fdeprecated-macro -ferror-limit 19 -fopenmp -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -x c++ PairCorrEstimator-40412c.cpp
1.	<eof> parser at end of file
2.	Optimizer
3.	Running pass "function<eager-inv>(float2int,lower-constant-intrinsics,chr,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-use-loop-info;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>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-unroll<O3>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;hoist-loads-stores-with-cond-faulting;no-sink-common-insts;speculate-blocks;simplify-cond-branch;speculate-unpredictables>)" on module "PairCorrEstimator-40412c.cpp"
4.	Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "_ZN11qmcplusplus17PairCorrEstimator15set_norm_factorEv"
 #0 0x00005590c1746c00 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x2cb6c00)
 #1 0x00005590c174400f llvm::sys::RunSignalHandlers() (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x2cb400f)
 #2 0x00005590c1744165 SignalHandler(int) Signals.cpp:0:0
 #3 0x00007fb046e53520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00005590bfa8725a llvm::BasicTTIImplBase<llvm::X86TTIImpl>::getIntrinsicInstrCost(llvm::IntrinsicCostAttributes const&, llvm::TargetTransformInfo::TargetCostKind) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0xff725a)
 #5 0x00005590c07fac92 llvm::TargetTransformInfo::getIntrinsicInstrCost(llvm::IntrinsicCostAttributes const&, llvm::TargetTransformInfo::TargetCostKind) const (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x1d6ac92)
 #6 0x00005590c31a87b9 llvm::VPWidenCallRecipe::computeCost(llvm::ElementCount, llvm::VPCostContext&) const (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x47187b9)
 #7 0x00005590c31ab682 llvm::VPRecipeBase::cost(llvm::ElementCount, llvm::VPCostContext&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x471b682)
 #8 0x00005590c31744af llvm::VPBasicBlock::cost(llvm::ElementCount, llvm::VPCostContext&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x46e44af)
 #9 0x00005590c317b4b5 llvm::VPRegionBlock::cost(llvm::ElementCount, llvm::VPCostContext&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x46eb4b5)
#10 0x00005590c305cfb4 llvm::LoopVectorizationPlanner::cost(llvm::VPlan&, llvm::ElementCount) const (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x45ccfb4)
#11 0x00005590c3064878 llvm::LoopVectorizationPlanner::computeBestVF() (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x45d4878)
#12 0x00005590c307c6fb llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x45ec6fb)
#13 0x00005590c307f711 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x45ef711)
#14 0x00005590c307fd87 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x45efd87)
#15 0x00005590c2bdf2e6 llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x414f2e6)
#16 0x00005590c10e652f llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x265652f)
#17 0x00005590bfaa9996 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x1019996)
#18 0x00005590c10e52ab llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x26552ab)
#19 0x00005590bfaaa356 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x101a356)
#20 0x00005590c10e32ed llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x26532ed)
#21 0x00005590c19d36b6 (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>&, std::unique_ptr<llvm::ToolOutputFile, std::default_delete<llvm::ToolOutputFile>>&, clang::BackendConsumer*) BackendUtil.cpp:0:0
#22 0x00005590c19d70e9 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x2f470e9)
#23 0x00005590c206a4b5 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x35da4b5)
#24 0x00005590c3cfd42c clang::ParseAST(clang::Sema&, bool, bool) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x526d42c)
#25 0x00005590c2318d19 clang::FrontendAction::Execute() (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x3888d19)
#26 0x00005590c22972b5 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x38072b5)
#27 0x00005590c23ef9d3 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0x395f9d3)
#28 0x00005590bfa2dc87 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0xf9dc87)
#29 0x00005590bfa269ea ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#30 0x00005590bfa29be3 clang_main(int, char**, llvm::ToolContext const&) (/scratch3/packages/llvm/main-20240902/bin/clang-20+0xf99be3)
#31 0x00005590bf955c4b main (/scratch3/packages/llvm/main-20240902/bin/clang-20+0xec5c4b)
#32 0x00007fb046e3ad90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#33 0x00007fb046e3ae40 call_init ./csu/../csu/libc-start.c:128:20
#34 0x00007fb046e3ae40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#35 0x00005590bfa26115 _start (/scratch3/packages/llvm/main-20240902/bin/clang-20+0xf96115)
PairCorrEstimator-40412c.sh: line 4: 840679 Segmentation fault      (core dumped) "/scratch3/packages/llvm/main-20240902/bin/clang-20" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "PairCorrEstimator.cpp" "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" "-mframe-pointer=none" "-menable-no-infs" "-menable-no-nans" "-fapprox-func" "-funsafe-math-optimizations" "-fno-signed-zeros" "-mreassociate" "-freciprocal-math" "-ffp-contract=fast" "-fno-rounding-math" "-ffast-math" "-ffinite-math-only" "-complex-range=basic" "-mconstructor-aliases" "-funwind-tables=2" "-target-cpu" "skylake-avx512" "-target-feature" "+prfchw" "-target-feature" "-cldemote" "-target-feature" "+avx" "-target-feature" "+aes" "-target-feature" "+sahf" "-target-feature" "+pclmul" "-target-feature" "-xop" "-target-feature" "+crc32" "-target-feature" "+xsaves" "-target-feature" "-avx512fp16" "-target-feature" "-usermsr" "-target-feature" "-sm4" "-target-feature" "-egpr" "-target-feature" "+sse4.1" "-target-feature" "-avx512ifma" "-target-feature" "+xsave" "-target-feature" "+sse4.2" "-target-feature" "-tsxldtrk" "-target-feature" "-sm3" "-target-feature" "-ptwrite" "-target-feature" "-widekl" "-target-feature" "+invpcid" "-target-feature" "+64bit" "-target-feature" "+xsavec" "-target-feature" "-avx10.1-512" "-target-feature" "-avx512vpopcntdq" "-target-feature" "+cmov" "-target-feature" "-avx512vp2intersect" "-target-feature" "+avx512cd" "-target-feature" "+movbe" "-target-feature" "-avxvnniint8" "-target-feature" "-ccmp" "-target-feature" "-amx-int8" "-target-feature" "-kl" "-target-feature" "-avx10.1-256" "-target-feature" "+evex512" "-target-feature" "-avxvnni" "-target-feature" "+rtm" "-target-feature" "+adx" "-target-feature" "+avx2" "-target-feature" "-hreset" "-target-feature" "-movdiri" "-target-feature" "-serialize" "-target-feature" "-sha512" "-target-feature" "-vpclmulqdq" "-target-feature" "+avx512vl" "-target-feature" "-uintr" "-target-feature" "-cf" "-target-feature" "+clflushopt" "-target-feature" "-raoint" "-target-feature" "-cmpccxadd" "-target-feature" "+bmi" "-target-feature" "-amx-tile" "-target-feature" "+sse" "-target-feature" "-avx10.2-256" "-target-feature" "-gfni" "-target-feature" "-avxvnniint16" "-target-feature" "-amx-fp16" "-target-feature" "-zu" "-target-feature" "-ndd" "-target-feature" "+xsaveopt" "-target-feature" "+rdrnd" "-target-feature" "+avx512f" "-target-feature" "-amx-bf16" "-target-feature" "-avx512bf16" "-target-feature" "-avx512vnni" "-target-feature" "-push2pop2" "-target-feature" "+cx8" "-target-feature" "+avx512bw" "-target-feature" "+sse3" "-target-feature" "+pku" "-target-feature" "-nf" "-target-feature" "+fsgsbase" "-target-feature" "-clzero" "-target-feature" "-mwaitx" "-target-feature" "-lwp" "-target-feature" "+lzcnt" "-target-feature" "-sha" "-target-feature" "-movdir64b" "-target-feature" "-ppx" "-target-feature" "-wbnoinvd" "-target-feature" "-enqcmd" "-target-feature" "-avx10.2-512" "-target-feature" "-avxneconvert" "-target-feature" "-tbm" "-target-feature" "-pconfig" "-target-feature" "-amx-complex" "-target-feature" "+ssse3" "-target-feature" "+cx16" "-target-feature" "+bmi2" "-target-feature" "+fma" "-target-feature" "+popcnt" "-target-feature" "-avxifma" "-target-feature" "+f16c" "-target-feature" "-avx512bitalg" "-target-feature" "-rdpru" "-target-feature" "+clwb" "-target-feature" "+mmx" "-target-feature" "+sse2" "-target-feature" "+rdseed" "-target-feature" "-avx512vbmi2" "-target-feature" "-prefetchi" "-target-feature" "-rdpid" "-target-feature" "-fma4" "-target-feature" "-avx512vbmi" "-target-feature" "-shstk" "-target-feature" "-vaes" "-target-feature" "-waitpkg" "-target-feature" "-sgx" "-target-feature" "+fxsr" "-target-feature" "+avx512dq" "-target-feature" "-sse4a" "-debugger-tuning=gdb" "-fdebug-compilation-dir=/scratch3/opt/qmcpack/build_clangPatched_real/src/QMCHamiltonians" "-fcoverage-compilation-dir=/scratch3/opt/qmcpack/build_clangPatched_real/src/QMCHamiltonians" "-sys-header-deps" "-D" "ADD_" "-D" "H5_USE_110_API" "-D" "HAVE_CONFIG_H" "-D" "HAVE_EINSPLINE" "-D" "HAVE_LIBBOOST" "-D" "HAVE_LIBFFTW" "-D" "HAVE_MKL" "-D" "HAVE_MKL_VML" "-D" "MPICH_SKIP_MPICXX" "-D" "OMPI_SKIP_MPICXX" "-D" "OPENMP_NO_COMPLEX" "-D" "_MPICC_H" "-D" "restrict=__restrict__" "-D" "NDEBUG" "-O3" "-Wvla" "-Wall" "-Wno-unused-variable" "-Wno-overloaded-virtual" "-Wno-unused-private-field" "-Wno-unused-local-typedef" "-Wsuggest-override" "-Wno-unknown-pragmas" "-Wmisleading-indentation" "-std=c++17" "-fdeprecated-macro" "-ferror-limit" "19" "-fopenmp" "-fgnuc-version=4.2.1" "-fskip-odr-check-in-gmf" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-vectorize-loops" "-vectorize-slp" "-faddrsig" "-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-x" "c++" "PairCorrEstimator-40412c.cpp"
```


commit 9b7491e8669126180253480821d5addde34874d0
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Tue Oct 15 23:07:16 2024 +0800

    [IR] Add support for `samesign` in `Operator::hasPoisonGeneratingFlags` (#112358)

    Fix https://github.com/llvm/llvm-project/issues/112356.

diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index f93ff8f6fc8a..199eb4d90f55 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -50,6 +50,8 @@ bool Operator::hasPoisonGeneratingFlags() const {
     if (auto *NNI = dyn_cast<PossiblyNonNegInst>(this))
       return NNI->hasNonNeg();
     return false;
+  case Instruction::ICmp:
+    return cast<ICmpInst>(this)->hasSameSign();
   default:
     if (const auto *FP = dyn_cast<FPMathOperator>(this))
       return FP->hasNoNaNs() || FP->hasNoInfs();

target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write)
declare void @llvm.assume(i1 noundef) #0

define i1 @icmp_and_inv_pow2_or_zero_ne_0(i32 %A, i32 %B) {
  %popcnt = tail call i32 @llvm.ctpop.i32(i32 %A)
  %cond = icmp ult i32 %popcnt, 2
  call void @llvm.assume(i1 %cond)
  %inv = xor i32 %B, -1
  %and = and i32 %A, %inv
  %cmp = icmp ne i32 %and, 0
  ret i1 %cmp
}

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

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

[InstCombine] `samesign` flag should be dropped

Reproducer:
```
define i1 @src(i32 %In) {
  %c1 = icmp samesign sgt i32 %In, -1
  %c2 = icmp samesign eq i32 %In, 1
  %V = select i1 %c1, i1 %c2, i1 false
  ret i1 %V
}

define i1 @tgt(i32 %In) {
  %c2 = icmp samesign eq i32 %In, 1
  ret i1 %c2
}
```

We should check this flag in `Operator::hasPoisonGeneratingFlags`.


commit e4b0655b297e4f4b0eb26548c8be48d527ebc178
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Mon Jun 10 03:17:01 2024 +0800

    [InstCombine] Fix missing argument typo in `InstCombinerImpl::foldICmpShlConstant` (#94899)

    Closes #94897.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 4203147bc6a5..3fce4a3c20b3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2441,9 +2441,10 @@ Instruction *InstCombinerImpl::foldICmpShlConstant(ICmpInst &Cmp,
       Type *TruncTy = ShType->getWithNewBitWidth(TypeBits - Amt);
       Constant *NewC =
           ConstantInt::get(TruncTy, RHSC.ashr(*ShiftAmt).trunc(TypeBits - Amt));
-      return new ICmpInst(
-          CmpPred, Builder.CreateTrunc(X, TruncTy, "", Shl->hasNoSignedWrap()),
-          NewC);
+      return new ICmpInst(CmpPred,
+                          Builder.CreateTrunc(X, TruncTy, "", /*IsNUW=*/false,
+                                              Shl->hasNoSignedWrap()),
+                          NewC);
     }
   }

wrong code at -O1 and above on x86_64-linux-gnu

This appears to be a recent regression as it doesn't reproduce with 18.1.0 and earlier.

Compiler Explorer: https://godbolt.org/z/T9b4a7z3v

```console
% clangtk -v
clang version 19.0.0git (https://github.com/llvm/llvm-project.git 338cbfef03e0ab58d7b52f3301928c58b194a1b4)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /local/suz-local/software/local/clang-trunk/bin
Build config: +assertions
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/11
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/11
Candidate multilib: .;@m64
Selected multilib: .;@m64
%
% clangtk -O0 small.c; ./a.out
% clangtk -O1 small.c
% ./a.out
Aborted
% cat small.c
int a;
char b(char c, char d) { return c - d; }
int main() {
  int e;
  for (a = -10; a > -11; a--)
    e = b(a, -1);
  if (e > -2)
    __builtin_abort();
  return 0;
}
```

Reproducer: https://alive2.llvm.org/ce/z/_3cyuT
```ll
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"

define i1 @src() {
entry:
  br label %for.body

for.body:
  %storemerge4 = phi i32 [ -10, %entry ], [ %dec, %for.body ]
  %dec = add nsw i32 %storemerge4, -1
  %cmp = icmp ugt i32 %dec, -11
  br i1 %cmp, label %for.body, label %for.end

for.end:
  %sub.i.le = shl nsw i32 %storemerge4, 24
  %cmp2 = icmp ugt i32 %sub.i.le, -50331648
  ret i1 %cmp2
}

define i1 @tgt() {
entry:
  br label %for.body

for.body:
  %storemerge4 = phi i32 [ -10, %entry ], [ %dec, %for.body ]
  %dec = add nsw i32 %storemerge4, -1
  %cmp = icmp ugt i32 %dec, -11
  br i1 %cmp, label %for.body, label %for.end

for.end:
  %0 = trunc nuw i32 %storemerge4 to i8
  %cmp2 = icmp ugt i8 %0, -3
  ret i1 %cmp2
}
```

`nuw` flag is incorrectly added.

Caused by https://github.com/llvm/llvm-project/commit/5c7c1f6aba467b1c5a51d58fc591314ecd7147ce.


commit 97e3220d6312ae00bcbe08673f218bd0f705776b
Author: Nikita Popov <npopov@redhat.com>
Date:   Mon Jan 8 15:49:47 2024 +0100

    [InstSimplify] Consider bitcast as potential cross-lane operation

    The bitcast might change the number of vector lanes, in which case
    it will be a cross-lane operation.

    Fixes https://github.com/llvm/llvm-project/issues/77320.

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 241bdd81b75a..d0c27cae0dff 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4313,7 +4313,7 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
     // For vector types, the simplification must hold per-lane, so forbid
     // potentially cross-lane operations like shufflevector.
     if (!I->getType()->isVectorTy() || isa<ShuffleVectorInst>(I) ||
-        isa<CallBase>(I))
+        isa<CallBase>(I) || isa<BitCastInst>(I))
       return nullptr;
   }

define <4 x i32> @select_vector_cmp_with_bitcasts(<2 x i64> %x, <4 x i32> %y) {
  %x.bc = bitcast <2 x i64> %x to <4 x i32>
  %y.bc = bitcast <4 x i32> %y to <2 x i64>
  %sub = sub <2 x i64> %x, %y.bc
  %sub.bc = bitcast <2 x i64> %sub to <4 x i32>
  %cmp = icmp eq <4 x i32> %y, %x.bc
  %sel = select <4 x i1> %cmp, <4 x i32> %sub.bc, <4 x i32> zeroinitializer
  ret <4 x i32> %sel
}

define i8 @select_or_disjoint_eq(i8 %x, i8 %y) {
  %cmp = icmp eq i8 %x, %y
  %or = or disjoint i8 %x, %y
  %sel = select i1 %cmp, i8 %x, i8 %or
  ret i8 %sel
}

[InstSimplify] Miscompile with select of vectors and bitcast

https://alive2.llvm.org/ce/z/xhCFyk

```llvm
define <4 x i32> @src(<2 x i64> %x, <4 x i32> %y) {
  %x.bc = bitcast <2 x i64> %x to <4 x i32>
  %y.bc = bitcast <4 x i32> %y to <2 x i64>
  %sub = sub <2 x i64> %x, %y.bc
  %sub.bc = bitcast <2 x i64> %sub to <4 x i32>
  %cmp = icmp eq <4 x i32> %y, %x.bc
  %sel = select <4 x i1> %cmp, <4 x i32> %sub.bc, <4 x i32> zeroinitializer
  ret <4 x i32> %sel
}

define <4 x i32> @tgt(<2 x i64> %x, <4 x i32> %y) {
  ret <4 x i32> zeroinitializer
}
```


commit 27eaa8a40ef338bea611f693fa8e810b1fc8d78d
Author: Maurice Heumann <MauriceHeumann@gmail.com>
Date:   Thu Dec 5 16:57:27 2024 +0100

    [InstCombine] Prevent infinite loop with two shifts (#118806)

    The following pattern: `(C2 << X) << C1` will usually be transformed
    into `(C2 << C1) << X`, essentially swapping `X` and `C1`.

    However, this should only be done when `C1` is an immediate constant,
    otherwise thiscan lead to both constants being swapped forever.

    This fixes #118798.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 10c3ccdb2243..d511e79e3e48 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -427,7 +427,8 @@ Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
       if (Instruction *R = FoldOpIntoSelect(I, SI))
         return R;

-  if (Constant *CUI = dyn_cast<Constant>(Op1))
+  Constant *CUI;
+  if (match(Op1, m_ImmConstant(CUI)))
     if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I))
       return Res;

@c = external constant i8
@c2 = external constant i8

define i64 @testfunc() {
  %shl1 = shl i64 1, ptrtoint (ptr @c2 to i64)
  %shl2 = shl i64 %shl1, ptrtoint (ptr @c to i64)
  ret i64 %shl2
}

[InstCombine] Infinite loop when combining two `shl` instructions

The following sample triggers an infinite loop in instcombine:

```
@c = external constant i8
@c2 = external constant i8

define i16 @testfunc() {
entry:
  %0 = shl i64 1, ptrtoint (ptr @c2 to i64)
  %1 = shl i64 %0, ptrtoint (ptr @c to i64)
  %2 = inttoptr i64 %1 to ptr
  %3 = load i16, ptr %2, align 1
  ret i16 %3
}
```

https://godbolt.org/z/WP6YvGjPq

I have a potential fix and will create a PR soon


commit f7ef0721d60f85e1f699f8d1b83d4402ae19b122
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Sun Dec 1 20:11:09 2024 +0800

    [SCEV] Do not allow refinement in the rewriting of BEValue (#117152)

    See the following case:
    ```
    ; bin/opt -passes="print<scalar-evolution>" test.ll --disable-output
    define i32 @widget() {
    b:
      br label %b1

    b1:                                              ; preds = %b5, %b
      %phi = phi i32 [ 0, %b ], [ %udiv6, %b5 ]
      %phi2 = phi i32 [ 1, %b ], [ %add, %b5 ]
      %icmp = icmp eq i32 %phi, 0
      br i1 %icmp, label %b3, label %b8

    b3:                                              ; preds = %b1
      %udiv = udiv i32 10, %phi2
      %urem = urem i32 %udiv, 10
      %icmp4 = icmp eq i32 %urem, 0
      br i1 %icmp4, label %b7, label %b5

    b5:                                              ; preds = %b3
      %udiv6 = udiv i32 %phi2, 0
      %add = add i32 %phi2, 1
      br label %b1

    b7:                                              ; preds = %b3
      ret i32 5

    b8:                                              ; preds = %b1
      ret i32 7
    }
    ```
    ```
    %phi2 = phi i32 [ 1, %b ], [ %add, %b5 ] -->  {1,+,1}<nuw><nsw><%b1>
    %udiv6 = udiv i32 %phi2, 0 --> ({1,+,1}<nuw><nsw><%b1> /u 0)
    %phi = phi i32 [ 0, %b ], [ %udiv6, %b5 ] --> ({0,+,1}<nuw><nsw><%b1> /u 0)
    ```
    `ScalarEvolution::createAddRecFromPHI` gives a wrong SCEV result for
    `%phi`:

    https://github.com/llvm/llvm-project/blob/d7d6fb1804415b0f3e7f1cc9290bfb3d711cb707/llvm/lib/Analysis/ScalarEvolution.cpp#L5926-L5950
    It converts `phi(0, ({1,+,1}<nuw><nsw><%b1> /u 0))` into `phi(0 / 0,
    ({1,+,1}<nuw><nsw><%b1> /u 0))`. Then it simplifies the expr into
    `{0,+,1}<nuw><nsw><%b1> /u 0`.

    As we did in
    https://github.com/llvm/llvm-project/commit/acd700a24b6f767413db3d525e06d03e4245aa40,
    this patch disallows udiv simplification if we cannot prove that the
    denominator is a well-defined non-zero value.

    Fixes https://github.com/llvm/llvm-project/issues/117133.

diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 885c5985f9d2..b20c6a13cb6b 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -2187,6 +2187,9 @@ private:
   bool isGuaranteedToTransferExecutionTo(const Instruction *A,
                                          const Instruction *B);

+  /// Returns true if \p Op is guaranteed not to cause immediate UB.
+  bool isGuaranteedNotToCauseUB(const SCEV *Op);
+
   /// Returns true if \p Op is guaranteed to not be poison.
   static bool isGuaranteedNotToBePoison(const SCEV *Op);

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index c3f296b9ff33..882e938e69c0 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -4307,15 +4307,7 @@ ScalarEvolution::getSequentialMinMaxExpr(SCEVTypes Kind,
   }

   for (unsigned i = 1, e = Ops.size(); i != e; ++i) {
-    bool MayBeUB = SCEVExprContains(Ops[i], [this](const SCEV *S) {
-      auto *UDiv = dyn_cast<SCEVUDivExpr>(S);
-      // The UDiv may be UB if the divisor is poison or zero. Unless the divisor
-      // is a non-zero constant, we have to assume the UDiv may be UB.
-      return UDiv && (!isKnownNonZero(UDiv->getOperand(1)) ||
-                      !isGuaranteedNotToBePoison(UDiv->getOperand(1)));
-    });
-
-    if (MayBeUB)
+    if (!isGuaranteedNotToCauseUB(Ops[i]))
       continue;
     // We can replace %x umin_seq %y with %x umin %y if either:
     //  * %y being poison implies %x is also poison.
@@ -5933,18 +5925,22 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
     // We can generalize this saying that i is the shifted value of BEValue
     // by one iteration:
     //   PHI(f(0), f({1,+,1})) --> f({0,+,1})
-    const SCEV *Shifted = SCEVShiftRewriter::rewrite(BEValue, L, *this);
-    const SCEV *Start = SCEVInitRewriter::rewrite(Shifted, L, *this, false);
-    if (Shifted != getCouldNotCompute() &&
-        Start != getCouldNotCompute()) {
-      const SCEV *StartVal = getSCEV(StartValueV);
-      if (Start == StartVal) {
-        // Okay, for the entire analysis of this edge we assumed the PHI
-        // to be symbolic.  We now need to go back and purge all of the
-        // entries for the scalars that use the symbolic expression.
-        forgetMemoizedResults(SymbolicName);
-        insertValueToMap(PN, Shifted);
-        return Shifted;
+
+    // Do not allow refinement in rewriting of BEValue.
+    if (isGuaranteedNotToCauseUB(BEValue)) {
+      const SCEV *Shifted = SCEVShiftRewriter::rewrite(BEValue, L, *this);
+      const SCEV *Start = SCEVInitRewriter::rewrite(Shifted, L, *this, false);
+      if (Shifted != getCouldNotCompute() && Start != getCouldNotCompute() &&
+          ::impliesPoison(BEValue, Start)) {
+        const SCEV *StartVal = getSCEV(StartValueV);
+        if (Start == StartVal) {
+          // Okay, for the entire analysis of this edge we assumed the PHI
+          // to be symbolic.  We now need to go back and purge all of the
+          // entries for the scalars that use the symbolic expression.
+          forgetMemoizedResults(SymbolicName);
+          insertValueToMap(PN, Shifted);
+          return Shifted;
+        }
       }
     }
   }
@@ -7324,6 +7320,16 @@ bool ScalarEvolution::isGuaranteedNotToBePoison(const SCEV *Op) {
   return PC.MaybePoison.empty();
 }

+bool ScalarEvolution::isGuaranteedNotToCauseUB(const SCEV *Op) {
+  return !SCEVExprContains(Op, [this](const SCEV *S) {
+    auto *UDiv = dyn_cast<SCEVUDivExpr>(S);
+    // The UDiv may be UB if the divisor is poison or zero. Unless the divisor
+    // is a non-zero constant, we have to assume the UDiv may be UB.
+    return UDiv && (!isKnownNonZero(UDiv->getOperand(1)) ||
+                    !isGuaranteedNotToBePoison(UDiv->getOperand(1)));
+  });
+}
+
 bool ScalarEvolution::isSCEVExprNeverPoison(const Instruction *I) {
   // Only proceed if we can prove that I does not yield poison.
   if (!programUndefinedIfPoison(I))

opt -S -disable-output "-passes=print<scalar-evolution>" < %s 2>&1

define i64 @test_poisonous(i64 %a, i32 %n) {
entry:
  br label %loop.body

loop.body:                                        ; preds = %loop.body, %entry
  %indvar1 = phi i32 [ 0, %entry ], [ %indvar1.next, %loop.body ]
  %indvar2 = phi i64 [ 0, %entry ], [ %mul, %loop.body ]
  %indvar1.next = add i32 %indvar1, 1
  %ext = zext i32 %indvar1.next to i64
  %mul = mul i64 %ext, %a
  %exitcond = icmp sgt i32 %indvar1.next, %n
  br i1 %exitcond, label %loop.exit, label %loop.body

loop.exit:                                        ; preds = %loop.body
  ret i64 %mul
}

[indvars] Miscompile when loop body has an operation with Undefined Behaviour

Here is the problematic IR:
```
define i32 @widget() {
bb:
  br label %bb1

bb1:                                              ; preds = %bb5, %bb
  %phi = phi i32 [ 0, %bb ], [ %udiv6, %bb5 ]
  %phi2 = phi i32 [ 1, %bb ], [ %add, %bb5 ]
  %icmp = icmp eq i32 %phi, 0
  br i1 %icmp, label %bb3, label %bb8

bb3:                                              ; preds = %bb1
  %udiv = udiv i32 10, %phi2
  %urem = urem i32 %udiv, 10
  %icmp4 = icmp eq i32 %urem, 0
  br i1 %icmp4, label %bb7, label %bb5

bb5:                                              ; preds = %bb3
  %udiv6 = udiv i32 %phi2, 0
  %add = add i32 %phi2, 1
  br label %bb1

bb7:                                              ; preds = %bb3
  ret i32 5

bb8:                                              ; preds = %bb1
  ret i32 7
}
```
produces incorrect IR when `indvars` pass is run. I suspect this is because of the `%udiv6 = udiv i32 %phi2, 0` divide by zero operation.
Look at the indvars transformation here: https://godbolt.org/z/cz1r5178h
The original IR must return 5, while the transformed IR returns 7

Proof of wrong transformation: https://alive2.llvm.org/ce/z/vPFhzg

Is this a fuzzer-generated test case?

> Is this a fuzzer-generated test case?

Hi @nikic , yes this test was fuzzer-generated.


commit 17bad1a9da228ade0c0b9b020ee99769b188d9b3
Author: Florian Hahn <flo@fhahn.com>
Date:   Fri Nov 1 20:51:25 2024 +0000

    [LV] Bail out on header phis in shouldConsiderInvariant.

    This fixes an infinite recursion in rare cases.

    Fixes https://github.com/llvm/llvm-project/issues/113794.

diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 659b4c30a58a..1c64bd2982d7 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -6389,9 +6389,11 @@ bool LoopVectorizationCostModel::shouldConsiderInvariant(Value *Op) {
     return false;
   // Consider Op invariant, if it or its operands aren't predicated
   // instruction in the loop. In that case, it is not trivially hoistable.
-  return !isa<Instruction>(Op) || !TheLoop->contains(cast<Instruction>(Op)) ||
-         (!isPredicatedInst(cast<Instruction>(Op)) &&
-          all_of(cast<Instruction>(Op)->operands(),
+  auto *OpI = dyn_cast<Instruction>(Op);
+  return !OpI || !TheLoop->contains(OpI) ||
+         (!isPredicatedInst(OpI) &&
+          (!isa<PHINode>(OpI) || OpI->getParent() != TheLoop->getHeader()) &&
+          all_of(OpI->operands(),
                  [this](Value *Op) { return shouldConsiderInvariant(Op); }));
 }

opt < %s -passes='function(loop-vectorize,instcombine)' -force-vector-width=2 -force-vector-interleave=1 -debug-only=loop-vectorize -disable-output -print-after=instcombine 2>&1

target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"

define i32 @red_phi_0(i32 %start, ptr %src) {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %red = phi i32 [ %start, %entry ], [ %red.next, %loop ]
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
  %red.next = add i32 0, %red
  %iv.next = add i64 %iv, 1
  %exitcond.not = icmp eq i64 %iv.next, 100
  br i1 %exitcond.not, label %exit, label %loop

exit:                                             ; preds = %loop
  %res = phi i32 [ %red.next, %loop ]
  ret i32 %res
}

target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"

define void @phi_three_incoming_values(ptr noalias %a, ptr noalias %b, i64 %n) {
entry:
  br label %for.body

for.body:                                         ; preds = %if.end, %entry
  %i = phi i64 [ %i.next, %if.end ], [ 0, %entry ]
  %tmp0 = getelementptr inbounds i32, ptr %a, i64 %i
  %tmp1 = load i32, ptr %tmp0, align 4
  %tmp2 = getelementptr inbounds i32, ptr %b, i64 %i
  %tmp3 = load i32, ptr %tmp2, align 4
  %tmp4 = icmp sgt i32 %tmp1, %tmp3
  br i1 %tmp4, label %if.then, label %if.end

if.then:                                          ; preds = %for.body
  %tmp5 = icmp sgt i32 %tmp1, 19
  br i1 %tmp5, label %if.end, label %if.else

if.else:                                          ; preds = %if.then
  %tmp6 = icmp slt i32 %tmp3, 4
  %tmp7 = select i1 %tmp6, i32 4, i32 5
  br label %if.end

if.end:                                           ; preds = %if.else, %if.then, %for.body
  %tmp8 = phi i32 [ 9, %for.body ], [ 3, %if.then ], [ %tmp7, %if.else ]
  store i32 %tmp8, ptr %tmp0, align 4
  %i.next = add i64 %i, 1
  %cond = icmp eq i64 %i, %n
  br i1 %cond, label %for.end, label %for.body

for.end:                                          ; preds = %if.end
  ret void
}

target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"

define void @phi_two_incoming_values(ptr noalias %a, ptr noalias %b, i64 %n) {
entry:
  br label %for.body

for.body:                                         ; preds = %if.end, %entry
  %i = phi i64 [ %i.next, %if.end ], [ 0, %entry ]
  %tmp0 = getelementptr inbounds i32, ptr %a, i64 %i
  %tmp1 = load i32, ptr %tmp0, align 4
  %tmp2 = getelementptr inbounds i32, ptr %b, i64 %i
  %tmp3 = icmp sgt i32 %tmp1, 0
  br i1 %tmp3, label %if.then, label %if.end

if.then:                                          ; preds = %for.body
  %tmp4 = add i32 %tmp1, 1
  br label %if.end

if.end:                                           ; preds = %if.then, %for.body
  %tmp5 = phi i32 [ %tmp1, %for.body ], [ %tmp4, %if.then ]
  store i32 %tmp5, ptr %tmp2, align 4
  %i.next = add i64 %i, 1
  %cond = icmp eq i64 %i, %n
  br i1 %cond, label %for.end, label %for.body

for.end:                                          ; preds = %if.end
  ret void
}

[clang] Segmentation fault in loop vectorization cost model during optimization pass

When I compiled this code with -O2 flag, it crashed:

```c
#include <stdint.h>
#define UNDEFINED(x) ((x), 0)
long b;
static int64_t j = 1;
static int64_t *k = &j;
static int64_t **l = &k;
int64_t m;
static uint64_t n;
int16_t ***o;
static int64_t ***p = &l;
uint64_t **q;

uint16_t
safe_mod_func_uint16_t_u_u(uint16_t ui1, uint16_t ui2)
{
  return
#ifndef UNSAFE
    (ui2 == 0) ?
    (UNDEFINED(ui1)) :
#endif
    (ui1 % ui2);
}

int64_t
safe_mod_func_int64_t_s_s(int64_t si1, int64_t si2)
{
  return
#ifndef UNSAFE
    ((si2 == 0) || ((si1 == INT64_MIN) && (si2 == (-1)))) ?
    (UNDEFINED(si1)) :
#endif
    (si1 % si2);
}

int a(int, int, int, int, int) {}
long c(int d, int *e) {
  switch (d) {
  case 9:
    return b;
  case 8:
    return *e;
  }
}
long f(int g, long, int h) {
  long i = c(g, &h);
  return i;
}
int32_t r() { int32_t *s[] = {&k, &m}; }
int32_t t(int32_t *aa) {
  uint64_t ab = 2599693332;
  uint8_t ac = 142;
  for (; n <= 4; n++)
    *aa = (safe_mod_func_uint16_t_u_u(
               safe_mod_func_int64_t_s_s(a(0, 0, 0, 0, **l + 20) + **l, **q),
               ***o |= f(**l, 0, ***p)),
           **l + ac + ab - -1695273821 + *aa);
}
```

The crash is: clang: error: unable to execute command: Segmentation fault (core dumped)
clang: error: clang frontend command failed due to signal (use -v to see invocation)
Compiler returned: 254

Details can be found here: https://godbolt.org/z/3h9j7W6dG

This looks like a clang trunk regression: https://godbolt.org/z/MoKeds3ev


commit b634e057ddecc41dce046887d0f0854fed305374
Author: Han-Kuan Chen <hankuan.chen@sifive.com>
Date:   Thu Jul 18 19:54:46 2024 +0800

    [SLP][REVEC] Fix false assumption of the source for castToScalarTyElem. (#99424)

    The argument V may come from adjustExtracts, which is the vector operand
    of ExtractElementInst. In addition, it is not existed in getTreeEntry.

    The vector operand of ExtractElementInst may have a type of <1 x Ty>,
    ensuring that the number of elements in ScalarTy and VecTy are equal.

    reference: https://github.com/llvm/llvm-project/issues/99411

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index d88c6307b994..b994645cece6 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11852,8 +11852,7 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
   Value *castToScalarTyElem(Value *V,
                             std::optional<bool> IsSigned = std::nullopt) {
     auto *VecTy = cast<VectorType>(V->getType());
-    assert(getNumElements(ScalarTy) < getNumElements(VecTy) &&
-           (getNumElements(VecTy) % getNumElements(ScalarTy) == 0));
+    assert(getNumElements(VecTy) % getNumElements(ScalarTy) == 0);
     if (VecTy->getElementType() == ScalarTy->getScalarType())
       return V;
     return Builder.CreateIntCast(

opt -mtriple x86_64-unknown-linux-gnu -passes=slp-vectorizer -S %s

define void @e() {
;
entry:
  %0 = extractelement <1 x i64> zeroinitializer, i64 0
  %bf.value = and i64 %0, 0
  %bf.set = or i64 0, %bf.value
  store i64 %bf.set, ptr getelementptr inbounds (i8, ptr null, i64 8), align 8
  %bf.value2 = and i64 0, 0
  %bf.set4 = or i64 0, %bf.value2
  store i64 %bf.set4, ptr null, align 8
  ret void
}

A/F: `getNumElements(ScalarTy) < getNumElements(VecTy) && (getNumElements(VecTy) % getNumElements(ScalarTy) == 0)' failed after 1813ffd

Several of our internal tests started hitting an assertion failure while building, one of which I bisected back to commit 1813ffd. Consider the following code:
```c++
typedef long long __m64 __attribute__((__vector_size__(8), __aligned__(8)));
static __inline__ long long foo(__m64 m) { return (long long) m; }
struct c {
  long a : 43;
  long b : 61;
} d;
void e() {
  volatile __m64 f;
  long g, i = d.b = g = foo(f);
  d.a = i;
}
```
When compiled with optimizations with a compiler that includes 1813ffd, it hits an assertion failure:
```
$ ~/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang -c -O2 repro.cpp
clang: /home/dyung/src/upstream/llvm_clean_git/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:11853: llvm::Value* llvm::slpvectorizer::BoUpSLP::ShuffleInstructionBuilder::castToScalarTyElem(llvm::Value*, std::optional<bool>): Assertion `getNumElements(ScalarTy) < getNumElements(VecTy) && (getNumElements(VecTy) % getNumElements(ScalarTy) == 0)' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: /home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang -c -O2 repro.cpp
1.      <eof> parser at end of file
2.      Optimizer
3.      Running pass "function<eager-inv>(float2int,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-unroll<O2>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>)" on module "repro.cpp"
4.      Running pass "slp-vectorizer" on function "_Z7test119v"
 #0 0x00005650f775179f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x41a279f)
 #1 0x00005650f774f2fc llvm::sys::CleanupOnSignal(unsigned long) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x41a02fc)
 #2 0x00005650f76947e8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007ff89a3f9420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007ff899ec600b raise /build/glibc-LcI20x/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #5 0x00007ff899ea5859 abort /build/glibc-LcI20x/glibc-2.31/stdlib/abort.c:81:7
 #6 0x00007ff899ea5729 get_sysdep_segment_value /build/glibc-LcI20x/glibc-2.31/intl/loadmsgcat.c:509:8
 #7 0x00007ff899ea5729 _nl_load_domain /build/glibc-LcI20x/glibc-2.31/intl/loadmsgcat.c:970:34
 #8 0x00007ff899eb6fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #9 0x00005650f903005c llvm::slpvectorizer::BoUpSLP::ShuffleInstructionBuilder::castToScalarTyElem(llvm::Value*, std::optional<bool>) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5a8105c)
#10 0x00005650f9071f00 llvm::slpvectorizer::BoUpSLP::ShuffleInstructionBuilder::adjustExtracts(llvm::slpvectorizer::BoUpSLP::TreeEntry const*, llvm::MutableArrayRef<int>, llvm::ArrayRef<std::optional<llvm::TargetTransformInfo::ShuffleKind>>, unsigned int, bool&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5ac2f00)
#11 0x00005650f909dfdd llvm::Value* llvm::slpvectorizer::BoUpSLP::processBuildVector<llvm::slpvectorizer::BoUpSLP::ShuffleInstructionBuilder, llvm::Value*, llvm::IRBuilder<llvm::TargetFolder, llvm::IRBuilderDefaultInserter>, llvm::slpvectorizer::BoUpSLP>(llvm::slpvectorizer::BoUpSLP::TreeEntry const*, llvm::Type*, llvm::IRBuilder<llvm::TargetFolder, llvm::IRBuilderDefaultInserter>&, llvm::slpvectorizer::BoUpSLP&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5aeefdd)
#12 0x00005650f90a941a llvm::slpvectorizer::BoUpSLP::vectorizeTree(llvm::slpvectorizer::BoUpSLP::TreeEntry*, bool) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5afa41a)
#13 0x00005650f90a80e3 llvm::slpvectorizer::BoUpSLP::vectorizeOperand(llvm::slpvectorizer::BoUpSLP::TreeEntry*, unsigned int, bool) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5af90e3)
#14 0x00005650f90a9484 llvm::slpvectorizer::BoUpSLP::vectorizeTree(llvm::slpvectorizer::BoUpSLP::TreeEntry*, bool) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5afa484)
#15 0x00005650f90a7cdf llvm::slpvectorizer::BoUpSLP::vectorizeOperand(llvm::slpvectorizer::BoUpSLP::TreeEntry*, unsigned int, bool) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5af8cdf)
#16 0x00005650f90ac099 llvm::slpvectorizer::BoUpSLP::vectorizeTree(llvm::slpvectorizer::BoUpSLP::TreeEntry*, bool) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5afd099)
#17 0x00005650f90a7cdf llvm::slpvectorizer::BoUpSLP::vectorizeOperand(llvm::slpvectorizer::BoUpSLP::TreeEntry*, unsigned int, bool) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5af8cdf)
#18 0x00005650f90a9e6c llvm::slpvectorizer::BoUpSLP::vectorizeTree(llvm::slpvectorizer::BoUpSLP::TreeEntry*, bool) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5afae6c)
#19 0x00005650f90c7263 llvm::slpvectorizer::BoUpSLP::vectorizeTree(llvm::MapVector<llvm::Value*, llvm::SmallVector<llvm::Instruction*, 2u>, llvm::DenseMap<llvm::Value*, unsigned int, llvm::DenseMapInfo<llvm::Value*, void>, llvm::detail::DenseMapPair<llvm::Value*, unsigned int>>, llvm::SmallVector<std::pair<llvm::Value*, llvm::SmallVector<llvm::Instruction*, 2u>>, 0u>> const&, llvm::SmallVectorImpl<std::pair<llvm::Value*, llvm::Value*>>&, llvm::Instruction*) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5b18263)
#20 0x00005650f90cacbc llvm::slpvectorizer::BoUpSLP::vectorizeTree() (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5b1bcbc)
#21 0x00005650f90e045b llvm::SLPVectorizerPass::vectorizeStoreChain(llvm::ArrayRef<llvm::Value*>, llvm::slpvectorizer::BoUpSLP&, unsigned int, unsigned int, unsigned int&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5b3145b)
#22 0x00005650f90e1a5e llvm::SLPVectorizerPass::vectorizeStores(llvm::ArrayRef<llvm::StoreInst*>, llvm::slpvectorizer::BoUpSLP&, llvm::DenseSet<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, llvm::DenseMapInfo<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, void>>&)::'lambda'(std::set<std::pair<unsigned int, int>, llvm::SLPVectorizerPass::vectorizeStores(llvm::ArrayRef<llvm::StoreInst*>, llvm::slpvectorizer::BoUpSLP&, llvm::DenseSet<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, llvm::DenseMapInfo<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, void>>&)::StoreDistCompare, std::allocator<std::pair<unsigned int, int>>> const&)::operator()(std::set<std::pair<unsigned int, int>, llvm::SLPVectorizerPass::vectorizeStores(llvm::ArrayRef<llvm::StoreInst*>, llvm::slpvectorizer::BoUpSLP&, llvm::DenseSet<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, llvm::DenseMapInfo<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, void>>&)::StoreDistCompare, std::allocator<std::pair<unsigned int, int>>> const&) const SLPVectorizer.cpp:0:0
#23 0x00005650f90e39a0 llvm::SLPVectorizerPass::vectorizeStores(llvm::ArrayRef<llvm::StoreInst*>, llvm::slpvectorizer::BoUpSLP&, llvm::DenseSet<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, llvm::DenseMapInfo<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, void>>&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5b349a0)
#24 0x00005650f90e42c3 llvm::SLPVectorizerPass::vectorizeStoreChains(llvm::slpvectorizer::BoUpSLP&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5b352c3)
#25 0x00005650f90e57dd llvm::SLPVectorizerPass::runImpl(llvm::Function&, llvm::ScalarEvolution*, llvm::TargetTransformInfo*, llvm::TargetLibraryInfo*, llvm::AAResults*, llvm::LoopInfo*, llvm::DominatorTree*, llvm::AssumptionCache*, llvm::DemandedBits*, llvm::OptimizationRemarkEmitter*) (.part.0) SLPVectorizer.cpp:0:0
#26 0x00005650f90e6253 llvm::SLPVectorizerPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x5b37253)
#27 0x00005650f8baedb6 llvm::detail::PassModel<llvm::Function, llvm::SLPVectorizerPass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x55ffdb6)
#28 0x00005650f70f6421 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x3b47421)
#29 0x00005650f4cb9ca6 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x170aca6)
#30 0x00005650f70f4ded llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x3b45ded)
#31 0x00005650f4cbac56 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x170bc56)
#32 0x00005650f70f2f31 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x3b43f31)
#33 0x00005650f7a062c8 (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>&, std::unique_ptr<llvm::ToolOutputFile, std::default_delete<llvm::ToolOutputFile>>&, clang::BackendConsumer*) BackendUtil.cpp:0:0
#34 0x00005650f7a09645 (anonymous namespace)::EmitAssemblyHelper::EmitAssembly(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) BackendUtil.cpp:0:0
#35 0x00005650f7a09ce6 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x445ace6)
#36 0x00005650f808091c clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x4ad191c)
#37 0x00005650f9e7fe6c clang::ParseAST(clang::Sema&, bool, bool) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x68d0e6c)
#38 0x00005650f8080d28 clang::CodeGenAction::ExecuteAction() (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x4ad1d28)
#39 0x00005650f8318339 clang::FrontendAction::Execute() (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x4d69339)
#40 0x00005650f829a98e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x4ceb98e)
#41 0x00005650f8403dc6 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x4e54dc6)
#42 0x00005650f489f105 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x12f0105)
#43 0x00005650f489811a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#44 0x00005650f80c610d void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#45 0x00005650f7694cf0 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x40e5cf0)
#46 0x00005650f80c672f clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#47 0x00005650f808aa6c clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x4adba6c)
#48 0x00005650f808b4fd clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x4adc4fd)
#49 0x00005650f80935d5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x4ae45d5)
#50 0x00005650f489c37b clang_main(int, char**, llvm::ToolContext const&) (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x12ed37b)
#51 0x00005650f478ee1b main (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x11dfe1b)
#52 0x00007ff899ea7083 __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c:342:3
#53 0x00005650f4897bae _start (/home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin/clang+0x12e8bae)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 19.0.0 (https://github.com/llvm/llvm-project.git 1813ffd6b2eb04ee2c296a4399a18748740a439d)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/dyung/src/upstream/1813ffd6b2eb04ee2c296a4399a18748740a439d-linux/bin
Build config: +assertions
```
If built using the a compiler built from fa0e529 (the parent commit of 1813ffd), the compilation succeeds:
```
$ ~/src/upstream/fa0e52995929ab67dfb468d71fe793be5e1c7f03-linux/bin/clang -c -O2 repro.cpp
$
```

> @dyung https://godbolt.org/z/ofneqo6zK I don't see here. Am I missing anything?

I don't know if it reproduces on an ARM targeting compiler, I used an x86-64 targeting x86-64 compiler. Also the compiler currently used by godbolt was built from commit f56cdd4a45b7bbe84be5d4ba9442eb7071605efc which does not include 1813ffd6b2eb04ee2c296a4399a18748740a439d which introduced the issue.

Close the issue since https://github.com/llvm/llvm-project/commit/b634e057ddecc41dce046887d0f0854fed305374 is merged.


commit 654bb4e9f287f9ccb5142d1c62a9ab17c16e29d7
Author: Florian Hahn <flo@fhahn.com>
Date:   Sun Sep 1 20:35:28 2024 +0100

    [LV] Don't consider branches leaving loop in collectValuesToIgnore.

    Branches exiting the loop will remain regardless, so don't consider them
    in collectValuesToIgnore.

    This fixes another divergence between legacy and VPlan-based cost model.

    Fixes https://github.com/llvm/llvm-project/issues/106780.

diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index fa05b8dd2242..a8722db654f5 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -6817,6 +6817,9 @@ void LoopVectorizationCostModel::collectValuesToIgnore() {
     if (auto *Br = dyn_cast_or_null<BranchInst>(Op)) {
       BasicBlock *ThenBB = Br->getSuccessor(0);
       BasicBlock *ElseBB = Br->getSuccessor(1);
+      // Don't considers branches leaving the loop for simplification.
+      if (!TheLoop->contains(ThenBB) || !TheLoop->contains(ElseBB))
+        continue;
       bool ThenEmpty = IsEmptyBlock(ThenBB);
       bool ElseEmpty = IsEmptyBlock(ElseBB);
       if ((ThenEmpty && ElseEmpty) ||

opt -p loop-vectorize -mtriple riscv64-linux-gnu -mattr=+v,+f -S %s

target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"

define void @dead_load(ptr %p, i16 %start) {
entry:
  %start.ext = sext i16 %start to i64
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i64 [ %start.ext, %entry ], [ %iv.next, %loop ]
  %gep = getelementptr i16, ptr %p, i64 %iv
  store i16 0, ptr %gep, align 2
  %l = load i16, ptr %gep, align 2
  %iv.next = add i64 %iv, 3
  %cmp = icmp slt i64 %iv, 111
  br i1 %cmp, label %loop, label %exit

exit:                                             ; preds = %loop
  ret void
}

target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"

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

define i32 @cost_of_exit_branch_and_cond_insts(ptr %a, ptr %b, i1 %c, i16 %x) {
entry:
  br label %loop.header

loop.header:                                      ; preds = %loop.latch, %entry
  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
  br i1 %c, label %then, label %loop.exiting

then:                                             ; preds = %loop.header
  %gep = getelementptr inbounds i32, ptr %b, i32 %iv
  store i1 false, ptr %a, align 1
  store i32 0, ptr %gep, align 4
  br label %loop.exiting

loop.exiting:                                     ; preds = %then, %loop.header
  %iv.next = add i32 %iv, 1
  %umax = tail call i16 @llvm.umax.i16(i16 %x, i16 111)
  %umax.ext = zext i16 %umax to i32
  %sub = sub i32 770, %umax.ext
  %ec = icmp slt i32 %iv, %sub
  br i1 %ec, label %loop.latch, label %exit

loop.latch:                                       ; preds = %loop.exiting
  br label %loop.header

exit:                                             ; preds = %loop.exiting
  br label %return

return:                                           ; preds = %exit
  ret i32 0
}

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"

define i8 @dead_live_out_due_to_scalar_epilogue_required(ptr %src, ptr %dst) {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
  %idxprom = sext i32 %iv to i64
  %gep.src = getelementptr i8, ptr %src, i64 %idxprom
  %l = load i8, ptr %gep.src, align 1
  %gep.dst = getelementptr i8, ptr %dst, i64 %idxprom
  store i8 0, ptr %gep.dst, align 1
  %iv.next = add i32 %iv, 4
  %cmp = icmp ult i32 %iv, 1001
  br i1 %cmp, label %loop, label %exit

exit:                                             ; preds = %loop
  %r = phi i8 [ %l, %loop ]
  ret i8 %r
}

[VPlan] Assertion " VPlan cost model and legacy cost model disagreed"' failed.

Tested using ef7b18a53c0d186dcda1e322be6035407fdedb55

Testcase:
```c
unsigned short a;
extern int b;
void c(_Bool d, int e, long long f[], unsigned short g[][16],
       unsigned short h[][16], unsigned short i[][13], short j[][13],
       int k[][21], unsigned char l[][21][21], signed char m[][24]) {
  for (short n = 0; n < 5; n += -5532)
    for (char o = 0; o < 3; o += d)
      for (int p = 0; p < -({ g[d][1] > 0115 ? g[d][1] : 0115; }) + 770; p++)
        for (_Bool q = 0; q < (_Bool)e; q = 5)
          for (_Bool r = 2048749519 ? 8 ? f[d] : 0 : 0; r < 1; r = h)
            b = a = 0;
}
void hash();
unsigned short a = 6;
long long f[6];
unsigned short g[6][16];
unsigned short h[1][16];
unsigned short i[1][13];
short j[1][13];
int k[1][21];
unsigned char l[1][21][21];
signed char m[1][24];
int main() {
  for (long s = 0; s < 6; ++s)
    f[s] = 6;
  for (long s = 0; s < 16; ++s)
    for (long n = 0; n < 16; ++n)
      g[s][n] = 7;
  c(1, 407418382874, f, g, h, i, j, k, l, m);
  hash(a);
}
```
c command:
```
/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/clang -fno-strict-aliasing -march=rv64gcv -flto -O3 -fuse-ld=lld red.c -o rv64gcv.out -w
```

LLVM 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"

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

define i32 @main(ptr %a) #1 {
entry:
  br label %for.cond22.preheader.us.us76.us.us.us.us.i.1

for.cond22.preheader.us.us76.us.us.us.us.i.1:     ; preds = %for.cond22.preheader.us.us76.us.us.us.usthread-pre-split.i.1, %entry
  %p.072.us.us77.us.us.us.us.i.1 = phi i32 [ %inc.us.us80.us.us.us.us.i.1, %for.cond22.preheader.us.us76.us.us.us.usthread-pre-split.i.1 ], [ 0, %entry ]
  br i1 false, label %for.body41.lr.ph.us.us.us.us.us.us.us.i.1, label %for.cond22.for.cond.cleanup28_crit_edge.us.us.us.us.us.us.i.1

for.body41.lr.ph.us.us.us.us.us.us.us.i.1:        ; preds = %for.cond22.preheader.us.us76.us.us.us.us.i.1
  store i1 false, ptr %a, align 1
  store i32 0, ptr null, align 4
  br label %for.cond22.for.cond.cleanup28_crit_edge.us.us.us.us.us.us.i.1

for.cond22.for.cond.cleanup28_crit_edge.us.us.us.us.us.us.i.1: ; preds = %for.body41.lr.ph.us.us.us.us.us.us.us.i.1, %for.cond22.preheader.us.us76.us.us.us.us.i.1
  %inc.us.us80.us.us.us.us.i.1 = add i32 %p.072.us.us77.us.us.us.us.i.1, 1
  %narrow.us.us81.us.us.us.us.i.1 = tail call i16 @llvm.umax.i16(i16 0, i16 0)
  %spec.select.us.us82.us.us.us.us.i.1 = zext i16 %narrow.us.us81.us.us.us.us.i.1 to i32
  %add.us.us83.us.us.us.us.i.1 = sub i32 770, %spec.select.us.us82.us.us.us.us.i.1
  %cmp18.us.us84.us.us.us.us.i.1 = icmp slt i32 %p.072.us.us77.us.us.us.us.i.1, %add.us.us83.us.us.us.us.i.1
  br i1 %cmp18.us.us84.us.us.us.us.i.1, label %for.cond22.preheader.us.us76.us.us.us.usthread-pre-split.i.1, label %for.cond22.for.cond.cleanup28_crit_edge.us.us.us.us.us.us.i.1.for.cond.cleanup20.us.us.us.us.i.1_crit_edge

for.cond22.for.cond.cleanup28_crit_edge.us.us.us.us.us.us.i.1.for.cond.cleanup20.us.us.us.us.i.1_crit_edge: ; preds = %for.cond22.for.cond.cleanup28_crit_edge.us.us.us.us.us.us.i.1
  br label %for.cond.cleanup20.us.us.us.us.i.1

for.cond.cleanup20.us.us.us.us.i.1:               ; preds = %for.cond22.for.cond.cleanup28_crit_edge.us.us.us.us.us.us.i.1.for.cond.cleanup20.us.us.us.us.i.1_crit_edge
  ret i32 0

for.cond22.preheader.us.us76.us.us.us.usthread-pre-split.i.1: ; preds = %for.cond22.for.cond.cleanup28_crit_edge.us.us.us.us.us.us.i.1
  br label %for.cond22.preheader.us.us76.us.us.us.us.i.1
}

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #1 = { "target-features"="+64bit,+a,+c,+d,+f,+m,+relax,+v,+zicsr,+zifencei,+zmmul,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+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,-zvl256b,-zvl32768b,-zvl4096b,-zvl512b,-zvl65536b,-zvl8192b" }
```

Command/backtrace:
```
> /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt -passes=loop-vectorize reduced.ll -S
opt: /scratch/tc-testing/tc-compiler-fuzz-trunk/llvm/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:7366: llvm::VectorizationFactor llvm::LoopVectorizationPlanner::computeBestVF(): Assertion `(BestFactor.Width == LegacyVF.Width || planContainsAdditionalSimplifications(getPlanFor(BestFactor.Width), CostCtx, OrigLoop)) && " 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 reduced.ll -S
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 "main"
 #0 0x00005e8221f7d690 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x301e690)
 #1 0x00005e8221f7aa9f llvm::sys::RunSignalHandlers() (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x301ba9f)
 #2 0x00005e8221f7abf5 SignalHandler(int) Signals.cpp:0:0
 #3 0x0000772c88c42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x0000772c88c969fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x0000772c88c969fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x0000772c88c969fc pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x0000772c88c42476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x0000772c88c287f3 abort ./stdlib/abort.c:81:7
 #9 0x0000772c88c2871b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x0000772c88c39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#11 0x00005e8220f4a3e0 llvm::LoopVectorizationPlanner::computeBestVF() (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x1feb3e0)
#12 0x00005e8220f60ffb llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x2001ffb)
#13 0x00005e8220f64011 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x2005011)
#14 0x00005e8220f64687 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x2005687)
#15 0x00005e821fdc0fb6 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+0xe61fb6)
#16 0x00005e8221d8858f 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+0x2e2958f)
#17 0x00005e821fdc4146 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+0xe65146)
#18 0x00005e8221d8730b llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x2e2830b)
#19 0x00005e821fdc03e6 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+0xe613e6)
#20 0x00005e8221d8534d 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+0x2e2634d)
#21 0x00005e821f5e6ee6 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+0x687ee6)
#22 0x00005e821f5d8c71 optMain (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x679c71)
#23 0x0000772c88c29d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#24 0x0000772c88c29e40 call_init ./csu/../csu/libc-start.c:128:20
#25 0x0000772c88c29e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#26 0x00005e821f5cf025 _start (/scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt+0x670025)
zsh: IOT instruction (core dumped)  /scratch/tc-testing/tc-compiler-fuzz-trunk/build-gcv/build-llvm-linux/bin/opt
```
https://godbolt.org/z/ej1Gax953

Found via fuzzer

Related/prior issue: https://github.com/llvm/llvm-project/issues/106641

cc @fhahn