commit 75b922dccfc35ec25a520b1941e6682a300802b8
Author: Florian Hahn <flo@fhahn.com>
Date:   Sat Feb 1 21:40:58 2025 +0000

    [VPlan] Check VPWidenIntrinsicSC in VPRecipeWithIRFlags::classof.

    When VPWidenIntrinsicRecipe was changed to inhert from VPRecipeWithIRFlags,
    VPRecipeWithIRFlags::classof wasn't updated accordingly. Also check for
    VPWidenIntrinsicSC in VPRecipeWithIRFlags::classof.

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

diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 459222234bc3..87ef2dc6d8ea 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -1058,6 +1058,7 @@ public:
            R->getVPDefID() == VPRecipeBase::VPWidenEVLSC ||
            R->getVPDefID() == VPRecipeBase::VPWidenGEPSC ||
            R->getVPDefID() == VPRecipeBase::VPWidenCastSC ||
+           R->getVPDefID() == VPRecipeBase::VPWidenIntrinsicSC ||
            R->getVPDefID() == VPRecipeBase::VPReplicateSC ||
            R->getVPDefID() == VPRecipeBase::VPReverseVectorPointerSC ||
            R->getVPDefID() == VPRecipeBase::VPVectorPointerSC;

opt -p loop-vectorize -mcpu=neoverse-v2 -force-vector-width=4 -S %s

target triple = "aarch64-unknown-linux"

; Test case where we visit a VPWidenIntrinsic (for @llvm.fabs) with nnan flags.
; For https://github.com/llvm/llvm-project/issues/125301.
define void @check_widen_intrinsic_with_nnan(ptr noalias %dst.0, ptr noalias %dst.1, ptr noalias %src.1, ptr %src.2) {
;
entry:
  br label %loop.header

loop.header:
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
  %gep.src.1 = getelementptr inbounds double, ptr %src.1, i64 %iv
  %l.1 = load double, ptr %gep.src.1, align 8
  %abs = tail call nnan double @llvm.fabs.f64(double %l.1)
  %c.0 = fcmp olt double %abs, 1.000000e+00
  br i1 %c.0, label %then, label %else

then:
  %l.2 = load double, ptr %src.2, align 8
  %iv.sub.1 = add nsw i64 %iv, -1
  %gep.iv.sub.1 = getelementptr double, ptr %dst.0, i64 %iv.sub.1
  store double 0.000000e+00, ptr %gep.iv.sub.1, align 8
  %c.1 = fcmp oeq double %l.2, 0.000000e+00
  br i1 %c.1, label %merge, label %loop.latch

else:
  %iv.sub.2 = add nsw i64 %iv, -1
  %gep.iv.sub.2 = getelementptr double, ptr %dst.0, i64 %iv.sub.2
  store double 0.000000e+00, ptr %gep.iv.sub.2, align 8
  br label %merge

merge:
  %merge.iv = phi i64 [ %iv.sub.2, %else ], [ %iv.sub.1, %then ]
  %gep.dst.1 = getelementptr inbounds i32, ptr %dst.1, i64 %merge.iv
  store i32 10, ptr %gep.dst.1, align 4
  br label %loop.latch

loop.latch:
  %iv.next = add nuw nsw i64 %iv, 1
  %exitcond.not = icmp eq i64 %iv.next, 1000
  br i1 %exitcond.not, label %exit, label %loop.header

exit:
ret void
}

declare double @llvm.fabs.f64(double)

[vplan] Assertion: found instruction with poison generating flags not covered by VPRecipeWithIRFlags

```
clang++ -O3 -mcpu=neoverse-v2 -c reduced.ll

clang++: llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp:1926: llvm::VPlanTransforms::dropPoisonGeneratingRecipes(llvm::VPlan&, const std::function<bool(llvm::BasicBlock*)>&)::<lambda(llvm::VPRecipeBase*)>: Assertion `(!Instr || !Instr->hasPoisonGeneratingFlags()) && "found instruction with poison generating flags not covered by " "VPRecipeWithIRFlags"' 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: clang++ -O3 -mcpu=neoverse-v2 -c reduced.ll
1.      Optimizer
2.      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-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-verify-fixpoint>,loop-unroll<O3>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;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 "reduced.ll"
3.      Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "foo"
 #0 0x0000aaaaaf09abe8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int)
 #1 0x0000aaaaaf098908 llvm::sys::RunSignalHandlers()
 #2 0x0000aaaaaf098c88 llvm::sys::CleanupOnSignal(unsigned long)
 #3 0x0000aaaaaefee5bc CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #4 0x0000fffff7fb08dc (linux-vdso.so.1+0x8dc)
 #5 0x0000fffff7c2f200 __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #6 0x0000fffff7bea67c gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #7 0x0000fffff7bd7130 abort ./stdlib/abort.c:81:7
 #8 0x0000fffff7be3fd0 __assert_fail_base ./assert/assert.c:89:7
 #9 0x0000fffff7be4040 __assert_perror_fail ./assert/assert-perr.c:31:1
#10 0x0000aaaab0bfd210 llvm::VPlanTransforms::dropPoisonGeneratingRecipes(llvm::VPlan&, std::function<bool (llvm::BasicBlock*)> const&)::'lambda'(llvm::VPRecipeBase*)::operator()(llvm::VPRecipeBase*) const (.isra.0) VPlanTransforms.cpp:0:0
#11 0x0000aaaab0c065b4 llvm::VPlanTransforms::dropPoisonGeneratingRecipes(llvm::VPlan&, std::function<bool (llvm::BasicBlock*)> const&)
#12 0x0000aaaab0b99078 llvm::LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(llvm::VFRange&)
#13 0x0000aaaab0b99634 llvm::LoopVectorizationPlanner::buildVPlansWithVPRecipes(llvm::ElementCount, llvm::ElementCount)
#14 0x0000aaaab0b99c1c llvm::LoopVectorizationPlanner::plan(llvm::ElementCount, unsigned int)
#15 0x0000aaaab0b9b05c llvm::LoopVectorizePass::processLoop(llvm::Loop*)
#16 0x0000aaaab0b9d464 llvm::LoopVectorizePass::runImpl(llvm::Function&)
#17 0x0000aaaab0b9da1c llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&)
#18 0x0000aaaab07856fc llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) PassBuilder.cpp:0:0
#19 0x0000aaaaaeb3fef8 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&)
#20 0x0000aaaaadbd51dc llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) NVPTXTargetMachine.cpp:0:0
#21 0x0000aaaaaeb3e97c llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&)
#22 0x0000aaaaadbd513c llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) NVPTXTargetMachine.cpp:0:0
#23 0x0000aaaaaeb3e3a4 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&)
#24 0x0000aaaaafa2b598 (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
#25 0x0000aaaaafa2e258 clang::emitBackendOutput(clang::CompilerInstance&, clang::CodeGenOptions&, 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*)
#26 0x0000aaaaafb69e8c clang::CodeGenAction::ExecuteAction()
#27 0x0000aaaaafef684c clang::FrontendAction::Execute()
#28 0x0000aaaaafe8bb30 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)
#29 0x0000aaaaaffe49b0 clang::ExecuteCompilerInvocation(clang::CompilerInstance*)
#30 0x0000aaaaadb8f874 cc1_main(llvm::ArrayRef<char const*>, char const*, void*)
#31 0x0000aaaaadb87f34 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#32 0x0000aaaaafcd7778 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
#33 0x0000aaaaaefeeac0 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>)
#34 0x0000aaaaafcd7d48 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
#35 0x0000aaaaafc9daf4 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const
#36 0x0000aaaaafc9e744 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const
#37 0x0000aaaaafca6268 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&)
#38 0x0000aaaaadb8c654 clang_main(int, char**, llvm::ToolContext const&)
#39 0x0000aaaaadb9c06c main
#40 0x0000fffff7bd73fc __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#41 0x0000fffff7bd74cc call_init ./csu/../csu/libc-start.c:128:20
#42 0x0000fffff7bd74cc __libc_start_main ./csu/../csu/libc-start.c:379:5
#43 0x0000aaaaadb87a24 _start
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 21.0.0git (https://github.com/llvm/llvm-project 82b923defe27cc46ecf3084f3a8f1c0d1c36199e)
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir:
Build config: +assertions
clang++: note: diagnostic msg: Error generating preprocessed source(s) - no preprocessable inputs.
```
```
# works ok
clang++ -O3 -mcpu=neoverse-n1 -c reduced.ll
```

```
; ModuleID = '<bc file>'
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"
target triple = "aarch64-unknown-linux-gnu"

define void @foo(ptr %0, ptr %1, ptr %bar, i64 %2) {
  br label %4

4:                                                ; preds = %5, %3
  br label %5

5:                                                ; preds = %26, %4
  %6 = phi i32 [ %27, %26 ], [ 0, %4 ]
  %7 = phi i64 [ %28, %26 ], [ %2, %4 ]
  %8 = icmp sgt i64 %7, 0
  br i1 %8, label %9, label %4

9:                                                ; preds = %5
  %10 = load double, ptr %1, align 8
  %11 = call nnan double @llvm.fabs.f64(double %10)
  %12 = fcmp olt double %11, 1.000000e+00
  br i1 %12, label %13, label %21

13:                                               ; preds = %9
  %14 = load double, ptr %bar, align 8
  %15 = zext i32 %6 to i64
  %16 = add i64 %15, -1
  %17 = getelementptr double, ptr %0, i64 %16
  store double 0.000000e+00, ptr %17, align 8
  %18 = fcmp oeq double %14, 0.000000e+00
  br i1 %18, label %19, label %26

19:                                               ; preds = %13
  %20 = getelementptr i32, ptr null, i64 %16
  store i32 0, ptr %20, align 4
  br label %26

21:                                               ; preds = %9
  %22 = zext i32 %6 to i64
  %23 = add i64 %22, -1
  %24 = getelementptr double, ptr %0, i64 %23
  store double 0.000000e+00, ptr %24, align 8
  %25 = getelementptr i32, ptr null, i64 %23
  store i32 0, ptr %25, align 4
  br label %26

26:                                               ; preds = %21, %19, %13
  %27 = add nsw i32 %6, 1
  %28 = add i64 %7, -1
  br label %5
}

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

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

@ashermancinelli it looks like `reduced.ll` is missing from the issue here? Could you attach it (or share a link to godbolt)?

@fhahn Sorry about that! I updated the description.


commit 892b4beeac50920e630f10905b2916295e2eb6d8
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Mon Feb 26 15:55:56 2024 +0800

    [GVN] Drop nsw/nuw flags when replacing the result of a with.overflow intrinsic with a overflowing binary operator (#82935)

    Alive2: https://alive2.llvm.org/ce/z/gyL7mn
    Fixes https://github.com/llvm/llvm-project/issues/82884.

diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 1373f5f7f449..075eeb5b19fd 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3369,11 +3369,17 @@ void llvm::patchReplacementInstruction(Instruction *I, Value *Repl) {

   // Patch the replacement so that it is not more restrictive than the value
   // being replaced.
+  WithOverflowInst *UnusedWO;
+  // When replacing the result of a llvm.*.with.overflow intrinsic with a
+  // overflowing binary operator, nuw/nsw flags may no longer hold.
+  if (isa<OverflowingBinaryOperator>(ReplInst) &&
+      match(I, m_ExtractValue<0>(m_WithOverflowInst(UnusedWO))))
+    ReplInst->dropPoisonGeneratingFlags();
   // Note that if 'I' is a load being replaced by some operation,
   // for example, by an arithmetic operation, then andIRFlags()
   // would just erase all math flags from the original arithmetic
   // operation, which is clearly not wanted and not needed.
-  if (!isa<LoadInst>(I))
+  else if (!isa<LoadInst>(I))
     ReplInst->andIRFlags(I);

   // FIXME: If both the original and replacement value are part of the

define i32 @pr82884(i32 %x) {
  %mul = mul nuw nsw i32 %x, %x
  call void @use(i32 %mul)
  %mul2 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %x, i32 %x)
  %ret = extractvalue { i32, i1 } %mul2, 0
  ret i32 %ret
}

declare void @use(i32)

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) #0

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

[GVN] GVNPass forgets to remove poison generating flags

```llvm
; ModuleID = '1851685_debug_2.e4807e3094afc004-cgu.0'
source_filename = "1851685_debug_2.e4807e3094afc004-cgu.0"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%Adt58 = type { %Adt50 }
%Adt50 = type { { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, { i16, i8, [5 x i8], i64 }, [8 x i32], { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr, [7 x i32], [3 x i32] }
%Adt53 = type { { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] } }
%Adt51 = type { { i64, i8, [7 x i8] }, { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, %Adt50, [8 x i32], i64, i64, [6 x i8], [10 x i8] }
%Adt59 = type { { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, i64, ptr, i32, i16, [1 x i8], [1 x i8] }

@vtable.0 = private unnamed_addr constant <{ ptr, [16 x i8], ptr, ptr, ptr }> <{ ptr @"_ZN4core3ptr85drop_in_place$LT$std..rt..lang_start$LT$$LP$$RP$$GT$..$u7b$$u7b$closure$u7d$$u7d$$GT$17he9a486ff76ea726fE", [16 x i8] c"\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00", ptr @"_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h91c73705548d2f78E", ptr @"_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h1cb78ba075200b22E", ptr @"_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h1cb78ba075200b22E" }>, align 8
@alloc_2cdd8ac758b4c372b56d8683306290e0 = private unnamed_addr constant <{ [15 x i8] }> <{ [15 x i8] c"hi:%ld lo:%ld\0A\00" }>, align 1

; std::sys_common::backtrace::__rust_begin_short_backtrace
; Function Attrs: noinline nonlazybind uwtable
define internal void @_ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h176fc8086015470dE(ptr %f) unnamed_addr #0 {
start:
; call core::ops::function::FnOnce::call_once
  call void @_ZN4core3ops8function6FnOnce9call_once17h23c7757b8dc992b5E(ptr %f)
  call void asm sideeffect "", "~{memory}"(), !srcloc !4
  ret void
}

; std::rt::lang_start::{{closure}}
; Function Attrs: inlinehint nonlazybind uwtable
define internal i32 @"_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h1cb78ba075200b22E"(ptr align 8 %_1) unnamed_addr #2 {
start:
  %self = alloca i8, align 1
  %_4 = load ptr, ptr %_1, align 8, !nonnull !5, !noundef !5
; call std::sys_common::backtrace::__rust_begin_short_backtrace
  call void @_ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h176fc8086015470dE(ptr %_4)
; call <() as std::process::Termination>::report
  %0 = call i8 @"_ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17hb8b4bfb25c4e0e48E"()
  store i8 %0, ptr %self, align 1
  %_6 = load i8, ptr %self, align 1, !noundef !5
  %_0 = zext i8 %_6 to i32
  ret i32 %_0
}

; core::ops::function::FnOnce::call_once{{vtable.shim}}
; Function Attrs: inlinehint nonlazybind uwtable
define internal i32 @"_ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h91c73705548d2f78E"(ptr %_1) unnamed_addr #2 {
start:
  %_2 = alloca {}, align 1
  %0 = load ptr, ptr %_1, align 8, !nonnull !5, !noundef !5
; call core::ops::function::FnOnce::call_once
  %_0 = call i32 @_ZN4core3ops8function6FnOnce9call_once17ha42f99eeb4429a31E(ptr %0)
  ret i32 %_0
}

; core::ops::function::FnOnce::call_once
; Function Attrs: inlinehint nonlazybind uwtable
define internal void @_ZN4core3ops8function6FnOnce9call_once17h23c7757b8dc992b5E(ptr %_1) unnamed_addr #2 {
start:
  %_2 = alloca {}, align 1
  call void %_1()
  ret void
}

; core::ops::function::FnOnce::call_once
; Function Attrs: inlinehint nonlazybind uwtable
define internal i32 @_ZN4core3ops8function6FnOnce9call_once17ha42f99eeb4429a31E(ptr %0) unnamed_addr #2 personality ptr @rust_eh_personality {
start:
  %1 = alloca { ptr, i32, [1 x i32] }, align 8
  %_2 = alloca {}, align 1
  %_1 = alloca ptr, align 8
  store ptr %0, ptr %_1, align 8
; invoke std::rt::lang_start::{{closure}}
  %_0 = invoke i32 @"_ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h1cb78ba075200b22E"(ptr align 8 %_1)
          to label %bb1 unwind label %cleanup

bb3:                                              ; preds = %cleanup
  %2 = load ptr, ptr %1, align 8, !noundef !5
  %3 = getelementptr inbounds i8, ptr %1, i64 8
  %4 = load i32, ptr %3, align 8, !noundef !5
  %5 = insertvalue { ptr, i32 } poison, ptr %2, 0
  %6 = insertvalue { ptr, i32 } %5, i32 %4, 1
  resume { ptr, i32 } %6

cleanup:                                          ; preds = %start
  %7 = landingpad { ptr, i32 }
          cleanup
  %8 = extractvalue { ptr, i32 } %7, 0
  %9 = extractvalue { ptr, i32 } %7, 1
  store ptr %8, ptr %1, align 8
  %10 = getelementptr inbounds i8, ptr %1, i64 8
  store i32 %9, ptr %10, align 8
  br label %bb3

bb1:                                              ; preds = %start
  ret i32 %_0
}

; core::ptr::drop_in_place<std::rt::lang_start<()>::{{closure}}>
; Function Attrs: inlinehint nonlazybind uwtable
define internal void @"_ZN4core3ptr85drop_in_place$LT$std..rt..lang_start$LT$$LP$$RP$$GT$..$u7b$$u7b$closure$u7d$$u7d$$GT$17he9a486ff76ea726fE"(ptr align 8 %_1) unnamed_addr #2 {
start:
  ret void
}

; core::hint::black_box
; Function Attrs: inlinehint nonlazybind uwtable
define internal void @_ZN4core4hint9black_box17h7d48bc7feb0af96eE(ptr sret({ i16, i8, [5 x i8], i64 }) align 8 %_0, ptr align 8 %dummy) unnamed_addr #2 {
start:
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %_0, ptr align 8 %dummy, i64 16, i1 false)
  call void asm sideeffect "", "r,~{memory}"(ptr %_0), !srcloc !4
  ret void
}

; core::hint::black_box
; Function Attrs: inlinehint nonlazybind uwtable
define internal void @_ZN4core4hint9black_box17ha89c3f9cb79c398cE() unnamed_addr #2 {
start:
  call void asm sideeffect "", "~{memory}"(), !srcloc !4
  ret void
}

; <() as std::process::Termination>::report
; Function Attrs: inlinehint nonlazybind uwtable
define internal i8 @"_ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17hb8b4bfb25c4e0e48E"() unnamed_addr #2 {
start:
  ret i8 0
}

; _1851685_debug_2::enter
; Function Attrs: nonlazybind uwtable
define internal void @_ZN16_1851685_debug_25enter17h7e9cae7a334c5019E() unnamed_addr #1 {
start:
  %_3 = alloca [6 x i32], align 4
  %_2 = alloca { i16, i8, [5 x i8], i64 }, align 8
  %0 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_2, i32 0, i32 1
  store i8 0, ptr %0, align 2
  store i16 0, ptr %_2, align 8
  %1 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_2, i32 0, i32 3
  store i64 0, ptr %1, align 8
  %2 = getelementptr inbounds [6 x i32], ptr %_3, i64 0, i64 0
  call void @llvm.memset.p0.i64(ptr align 4 %2, i8 0, i64 24, i1 false)
; call _1851685_debug_2::fn14
  call void @_ZN16_1851685_debug_24fn1417h1fc74d4c311bb23aE(ptr align 8 %_2, ptr align 4 %_3)
  ret void
}

; _1851685_debug_2::fn14
; Function Attrs: nonlazybind uwtable
define internal void @_ZN16_1851685_debug_24fn1417h1fc74d4c311bb23aE(ptr align 8 %_1, ptr align 4 %_2) unnamed_addr #1 {
start:
  %_16 = alloca i8, align 1
  %_15 = alloca %Adt58, align 16
  %_14 = alloca { i16, i8, [5 x i8], i64 }, align 8
  %_13 = alloca { { i16, i8, [5 x i8], i64 }, [6 x i32], i32, [1 x i32], [4 x i64] }, align 8
  %_12 = alloca %Adt53, align 16
  %_10 = alloca %Adt51, align 16
  %_7 = alloca %Adt59, align 8
  %_5 = alloca i128, align 16
  %0 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 1
  store i8 84, ptr %0, align 2
  store i16 -25440, ptr %_1, align 8
  %1 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 3
  store i64 -9223372036854775808, ptr %1, align 8
  br label %bb1

bb1:                                              ; preds = %bb4, %start
  store double 0x41A15ED4AE000000, ptr %_7, align 8
  %2 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 4
  %3 = load i16, ptr %_1, align 8, !noundef !5
  %4 = urem i16 %3, -3470
  store i16 %4, ptr %2, align 4
  %5 = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 3029947793098001587, i64 -3638983068927244405)
  %6 = extractvalue { i64, i1 } %5, 0
  %7 = extractvalue { i64, i1 } %5, 1
  store i64 %6, ptr %_10, align 16
  %8 = getelementptr inbounds i8, ptr %_10, i64 8
  %9 = zext i1 %7 to i8
  store i8 %9, ptr %8, align 8
  %10 = getelementptr inbounds i8, ptr %_10, i64 8
  %11 = load i8, ptr %10, align 8, !range !6, !noundef !5
  %12 = trunc i8 %11 to i1
  %13 = getelementptr inbounds i8, ptr %_10, i64 8
  %14 = load i8, ptr %13, align 8, !range !6, !noundef !5
  %15 = trunc i8 %14 to i1
  %_9 = xor i1 %12, %15
  %16 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 2
  store ptr %_10, ptr %16, align 8
  %17 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 1
  store i64 -1498547728408969452, ptr %17, align 8
  %18 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %19 = getelementptr inbounds %Adt50, ptr %18, i32 0, i32 2
  %20 = getelementptr inbounds [8 x i32], ptr %19, i64 0, i64 0
  store i32 168516996, ptr %20, align 16
  %21 = getelementptr inbounds [8 x i32], ptr %19, i64 0, i64 1
  store i32 245529160, ptr %21, align 4
  %22 = getelementptr inbounds [8 x i32], ptr %19, i64 0, i64 2
  store i32 1223136339, ptr %22, align 8
  %23 = getelementptr inbounds [8 x i32], ptr %19, i64 0, i64 3
  store i32 1622354325, ptr %23, align 4
  %24 = getelementptr inbounds [8 x i32], ptr %19, i64 0, i64 4
  store i32 -1002348909, ptr %24, align 16
  %25 = getelementptr inbounds [8 x i32], ptr %19, i64 0, i64 5
  store i32 1976405017, ptr %25, align 4
  %26 = getelementptr inbounds [8 x i32], ptr %19, i64 0, i64 6
  store i32 -1442509311, ptr %26, align 8
  %27 = getelementptr inbounds [8 x i32], ptr %19, i64 0, i64 7
  store i32 1165829790, ptr %27, align 4
  %28 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %29 = getelementptr inbounds %Adt50, ptr %28, i32 0, i32 3
  %30 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %29, i32 0, i32 2
  %31 = load double, ptr %_7, align 8, !noundef !5
  %32 = fneg double %31
  store double %32, ptr %30, align 16
  %33 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 3
  %34 = load i64, ptr %33, align 8, !noundef !5
  %_8 = xor i64 %34, -1
  store i64 7564290096487423208, ptr %_10, align 16
  %35 = getelementptr inbounds i8, ptr %_10, i64 8
  %36 = zext i1 %_9 to i8
  store i8 %36, ptr %35, align 8
  %37 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %38 = getelementptr inbounds %Adt50, ptr %37, i32 0, i32 3
  %39 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %38, i32 0, i32 1
  store i64 %_8, ptr %39, align 16
  %40 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 1
  %41 = load i64, ptr %_10, align 16, !noundef !5
  store i64 %41, ptr %40, align 8
  %42 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %43 = getelementptr inbounds %Adt50, ptr %42, i32 0, i32 3
  %44 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %43, i32 0, i32 1
  %45 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %44, i32 0, i32 5
; call _1851685_debug_2::fn15
  %46 = call i128 @_ZN16_1851685_debug_24fn1517hfe3f07cbb5faefb0E()
  store i128 %46, ptr %45, align 16
  %47 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %48 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %47, i32 0, i32 1
  %49 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 1
  %50 = load i64, ptr %49, align 8, !noundef !5
  %51 = trunc i64 %50 to i16
  store i16 %51, ptr %48, align 16
  %52 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 4
  %53 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 1
  %54 = load i64, ptr %53, align 8, !noundef !5
  store i64 %54, ptr %52, align 16
  %55 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %56 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %57 = getelementptr inbounds %Adt50, ptr %56, i32 0, i32 3
  %58 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %57, i32 0, i32 1
  %59 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %58, i32 0, i32 5
  %60 = load i128, ptr %59, align 16, !noundef !5
  %61 = ashr i128 %60, 0
  store i128 %61, ptr %55, align 16
  %62 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %63 = getelementptr inbounds %Adt50, ptr %62, i32 0, i32 3
  %64 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %63, i32 0, i32 2
  %65 = load double, ptr %64, align 16, !noundef !5
  %66 = fneg double %65
  store double %66, ptr %_7, align 8
  %67 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %68 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %67, i32 0, i32 2
  %69 = getelementptr inbounds i8, ptr %_10, i64 8
  %70 = load i8, ptr %69, align 8, !range !6, !noundef !5
  %71 = trunc i8 %70 to i1
  %72 = xor i1 %71, true
  %73 = zext i1 %72 to i8
  store i8 %73, ptr %68, align 2
  %74 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %75 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %74, i32 0, i32 4
  %76 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %77 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %76, i32 0, i32 1
  %78 = load i16, ptr %77, align 16, !noundef !5
  %79 = getelementptr inbounds [1 x i16], ptr %75, i64 0, i64 0
  store i16 %78, ptr %79, align 4
  %80 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %81 = getelementptr inbounds %Adt50, ptr %80, i32 0, i32 1
  %82 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %81, i32 0, i32 1
  %83 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 1
  %84 = load i8, ptr %83, align 2, !noundef !5
  store i8 %84, ptr %82, align 2
  %85 = getelementptr inbounds [6 x i32], ptr %_2, i64 0, i64 0
  store i32 -154507050, ptr %85, align 4
  %86 = getelementptr inbounds [6 x i32], ptr %_2, i64 0, i64 1
  store i32 2086635898, ptr %86, align 4
  %87 = getelementptr inbounds [6 x i32], ptr %_2, i64 0, i64 2
  store i32 468582002, ptr %87, align 4
  %88 = getelementptr inbounds [6 x i32], ptr %_2, i64 0, i64 3
  store i32 -21184342, ptr %88, align 4
  %89 = getelementptr inbounds [6 x i32], ptr %_2, i64 0, i64 4
  store i32 -1173629817, ptr %89, align 4
  %90 = getelementptr inbounds [6 x i32], ptr %_2, i64 0, i64 5
  store i32 -2078649110, ptr %90, align 4
  %91 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  store i128 0, ptr %91, align 16
  %92 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %_12, i32 0, i32 2
  %93 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %94 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %93, i32 0, i32 2
  %95 = load i8, ptr %94, align 2, !range !6, !noundef !5
  %96 = trunc i8 %95 to i1
  %97 = zext i1 %96 to i8
  store i8 %97, ptr %92, align 2
  %98 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %99 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %98, i32 0, i32 1
  %100 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %101 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %100, i32 0, i32 1
  %102 = load i16, ptr %101, align 16, !noundef !5
  %103 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %104 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %103, i32 0, i32 1
  %105 = load i16, ptr %104, align 16, !noundef !5
  %106 = mul i16 %102, %105
  store i16 %106, ptr %99, align 16
  %107 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 3
  store i32 630181660, ptr %107, align 8
  %108 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 3
  %109 = load i32, ptr %108, align 8, !noundef !5
  %110 = uitofp i32 %109 to double
  store double %110, ptr %_7, align 8
  %_11 = sub i64 0, %_8
  %111 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %112 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %113 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %112, i32 0, i32 1
  %114 = load i16, ptr %113, align 16, !noundef !5
  %115 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %111, i32 0, i32 1
  store i16 %114, ptr %115, align 16
  %116 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %117 = load i128, ptr %116, align 16, !noundef !5
  store i128 %117, ptr %111, align 16
  %118 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %111, i32 0, i32 2
  %119 = zext i1 %_9 to i8
  store i8 %119, ptr %118, align 2
  %120 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %121 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %120, i32 0, i32 4
  %122 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %111, i32 0, i32 4
  %123 = load i16, ptr %121, align 4
  store i16 %123, ptr %122, align 4
  %124 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 1
  %125 = load i64, ptr %124, align 8, !noundef !5
  %126 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 1
  %127 = load i64, ptr %126, align 8, !noundef !5
  %128 = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %125, i64 %127)
  %129 = extractvalue { i64, i1 } %128, 0
  %130 = extractvalue { i64, i1 } %128, 1
  store i64 %129, ptr %_10, align 16
  %131 = getelementptr inbounds i8, ptr %_10, i64 8
  %132 = zext i1 %130 to i8
  store i8 %132, ptr %131, align 8
  br label %bb3

bb3:                                              ; preds = %bb6, %bb1
  %133 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %134 = getelementptr inbounds %Adt50, ptr %133, i32 0, i32 3
  %135 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %134, i32 0, i32 2
  %136 = load double, ptr %_7, align 8, !noundef !5
  %137 = fdiv double %136, 0x92917F04BFA33
  store double %137, ptr %135, align 16
  %138 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 5
  store i64 -6496701646011298800, ptr %138, align 8
  %139 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %140 = getelementptr inbounds %Adt50, ptr %139, i32 0, i32 1
  %141 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %140, i32 0, i32 1
  %142 = load i8, ptr %141, align 2, !noundef !5
  %143 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 1
  store i8 %142, ptr %143, align 2
  %144 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 4
  %145 = load i16, ptr %144, align 4, !noundef !5
  store i16 %145, ptr %_1, align 8
  %146 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 3
  store i64 %_11, ptr %146, align 8
  %147 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %148 = getelementptr inbounds %Adt50, ptr %147, i32 0, i32 3
  %149 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %148, i32 0, i32 1
  %150 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %149, i32 0, i32 2
  %151 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 3
  %152 = load i32, ptr %151, align 8, !noundef !5
  store i32 %152, ptr %150, align 16
  %153 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %154 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %153, i32 0, i32 2
  %155 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %156 = load i128, ptr %155, align 16, !noundef !5
  %157 = icmp sge i128 %156, 0
  %158 = zext i1 %157 to i8
  store i8 %158, ptr %154, align 2
  %159 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %160 = getelementptr inbounds %Adt50, ptr %159, i32 0, i32 1
  %161 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %160, i32 0, i32 3
  %162 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 3
  %163 = load i64, ptr %162, align 8, !noundef !5
  %164 = and i64 %163, %_8
  store i64 %164, ptr %161, align 8
  %165 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 6
  %166 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %167 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %166, i32 0, i32 2
  %168 = load i8, ptr %167, align 2, !range !6, !noundef !5
  %169 = trunc i8 %168 to i1
  %170 = getelementptr inbounds [6 x i8], ptr %165, i64 0, i64 0
  %171 = zext i1 %169 to i8
  store i8 %171, ptr %170, align 16
  %172 = getelementptr inbounds i8, ptr %_10, i64 8
  %173 = load i8, ptr %172, align 8, !range !6, !noundef !5
  %174 = trunc i8 %173 to i1
  %175 = getelementptr inbounds [6 x i8], ptr %165, i64 0, i64 1
  %176 = zext i1 %174 to i8
  store i8 %176, ptr %175, align 1
  %177 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %_12, i32 0, i32 2
  %178 = load i8, ptr %177, align 2, !range !6, !noundef !5
  %179 = trunc i8 %178 to i1
  %180 = getelementptr inbounds [6 x i8], ptr %165, i64 0, i64 2
  %181 = zext i1 %179 to i8
  store i8 %181, ptr %180, align 2
  %182 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %_12, i32 0, i32 2
  %183 = load i8, ptr %182, align 2, !range !6, !noundef !5
  %184 = trunc i8 %183 to i1
  %185 = getelementptr inbounds [6 x i8], ptr %165, i64 0, i64 3
  %186 = zext i1 %184 to i8
  store i8 %186, ptr %185, align 1
  %187 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %188 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %187, i32 0, i32 2
  %189 = load i8, ptr %188, align 2, !range !6, !noundef !5
  %190 = trunc i8 %189 to i1
  %191 = getelementptr inbounds [6 x i8], ptr %165, i64 0, i64 4
  %192 = zext i1 %190 to i8
  store i8 %192, ptr %191, align 4
  %193 = getelementptr inbounds i8, ptr %_10, i64 8
  %194 = load i8, ptr %193, align 8, !range !6, !noundef !5
  %195 = trunc i8 %194 to i1
  %196 = getelementptr inbounds [6 x i8], ptr %165, i64 0, i64 5
  %197 = zext i1 %195 to i8
  store i8 %197, ptr %196, align 1
  %198 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %199 = getelementptr inbounds %Adt50, ptr %198, i32 0, i32 3
  %200 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %199, i32 0, i32 1
  %201 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %200, i32 0, i32 5
  %202 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %203 = load i128, ptr %202, align 16, !noundef !5
  store i128 %203, ptr %201, align 16
  %204 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 2
  %205 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %206 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %205, i32 0, i32 1
  %207 = load i16, ptr %206, align 16, !noundef !5
  %208 = sub i16 0, %207
  store i16 %208, ptr %204, align 8
  %209 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %210 = getelementptr inbounds %Adt50, ptr %209, i32 0, i32 4
  %211 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 1
  store ptr %211, ptr %210, align 16
  %212 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 5
  %213 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 1
  %214 = load i8, ptr %213, align 2, !noundef !5
  %215 = getelementptr inbounds [1 x i8], ptr %212, i64 0, i64 0
  store i8 %214, ptr %215, align 2
  %216 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 3
  %217 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %218 = getelementptr inbounds %Adt50, ptr %217, i32 0, i32 2
  %219 = load <8 x i32>, ptr %218, align 16
  store <8 x i32> %219, ptr %216, align 16
  %220 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %221 = getelementptr inbounds %Adt50, ptr %220, i32 0, i32 3
  %222 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %221, i32 0, i32 1
  %223 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %222, i32 0, i32 3
  %224 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 5
  %225 = load i64, ptr %224, align 8, !noundef !5
  %226 = trunc i64 %225 to i32
  store i32 %226, ptr %223, align 4
  %227 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 3
  %228 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %229 = getelementptr inbounds %Adt50, ptr %228, i32 0, i32 1
  %230 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %229, i32 0, i32 3
  %231 = load i64, ptr %230, align 8, !noundef !5
  %232 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %233 = getelementptr inbounds %Adt50, ptr %232, i32 0, i32 3
  %234 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %233, i32 0, i32 1
  %235 = load i64, ptr %234, align 16, !noundef !5
  %236 = xor i64 %231, %235
  store i64 %236, ptr %227, align 8
  %237 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %238 = getelementptr inbounds %Adt50, ptr %237, i32 0, i32 3
  %239 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %238, i32 0, i32 2
  %240 = load double, ptr %_7, align 8, !noundef !5
  store double %240, ptr %239, align 16
  %241 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_14, i32 0, i32 1
  %242 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 1
  %243 = load i8, ptr %242, align 2, !noundef !5
  %244 = xor i8 %243, -1
  store i8 %244, ptr %241, align 2
  %245 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %246 = getelementptr inbounds %Adt50, ptr %245, i32 0, i32 1
  %247 = getelementptr inbounds i8, ptr %_10, i64 8
  %248 = load i8, ptr %247, align 8, !range !6, !noundef !5
  %249 = trunc i8 %248 to i1
  %250 = zext i1 %249 to i16
  store i16 %250, ptr %246, align 16
  %251 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %252 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %253 = getelementptr inbounds %Adt50, ptr %252, i32 0, i32 3
  %254 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %253, i32 0, i32 1
  %255 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %254, i32 0, i32 3
  %256 = load i32, ptr %255, align 4, !noundef !5
  %257 = sext i32 %256 to i128
  store i128 %257, ptr %251, align 16
  %258 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %259 = getelementptr inbounds %Adt50, ptr %258, i32 0, i32 3
  %260 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %259, i32 0, i32 1
  %261 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %260, i32 0, i32 3
  %262 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %263 = getelementptr inbounds %Adt50, ptr %262, i32 0, i32 1
  %264 = load i16, ptr %263, align 16, !noundef !5
  %265 = zext i16 %264 to i32
  store i32 %265, ptr %261, align 4
  br label %bb4

bb4:                                              ; preds = %bb4, %bb3
  %266 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_14, i32 0, i32 1
  %267 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %268 = getelementptr inbounds %Adt50, ptr %267, i32 0, i32 3
  %269 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %268, i32 0, i32 1
  %270 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %269, i32 0, i32 3
  %271 = load i32, ptr %270, align 4, !noundef !5
  %272 = trunc i32 %271 to i8
  store i8 %272, ptr %266, align 2
  %273 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_14, i32 0, i32 1
  %274 = load i8, ptr %273, align 2, !noundef !5
  %275 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_13, i32 0, i32 1
  store i8 %274, ptr %275, align 2
  %276 = load i16, ptr %_1, align 8, !noundef !5
  store i16 %276, ptr %_13, align 8
  %277 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %278 = getelementptr inbounds %Adt50, ptr %277, i32 0, i32 1
  %279 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %278, i32 0, i32 3
  %280 = load i64, ptr %279, align 8, !noundef !5
  %281 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_13, i32 0, i32 3
  store i64 %280, ptr %281, align 8
  %282 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_14, i32 0, i32 3
  %283 = getelementptr inbounds %Adt59, ptr %_7, i32 0, i32 4
  %284 = load i16, ptr %283, align 4, !noundef !5
  %285 = zext i16 %284 to i64
  store i64 %285, ptr %282, align 8
  %286 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %287 = getelementptr inbounds %Adt50, ptr %286, i32 0, i32 3
  %288 = load i64, ptr %_10, align 16, !noundef !5
  %289 = sext i64 %288 to i128
  store i128 %289, ptr %287, align 16
  %290 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 1
  %291 = getelementptr inbounds { i128, i16, i8, [1 x i8], [1 x i16], [5 x i16] }, ptr %290, i32 0, i32 2
  %292 = load i8, ptr %291, align 2, !range !6, !noundef !5
  %293 = trunc i8 %292 to i1
  %294 = getelementptr inbounds i8, ptr %_10, i64 8
  %295 = load i8, ptr %294, align 8, !range !6, !noundef !5
  %296 = trunc i8 %295 to i1
  %297 = and i1 %293, %296
  %298 = zext i1 %297 to i8
  store i8 %298, ptr %_16, align 1
  %299 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 1
  %300 = getelementptr inbounds { i64, i64, i64 }, ptr %299, i32 0, i32 2
  %301 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 3
  %302 = load i64, ptr %301, align 8, !noundef !5
  %303 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_14, i32 0, i32 3
  %304 = load i64, ptr %303, align 8, !noundef !5
  %305 = xor i64 %302, %304
  store i64 %305, ptr %300, align 8
  %306 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_13, i32 0, i32 1
  %307 = load i8, ptr %306, align 2, !noundef !5
  %308 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_14, i32 0, i32 1
  store i8 %307, ptr %308, align 2
  %309 = load i16, ptr %_1, align 8, !noundef !5
  store i16 %309, ptr %_14, align 8
  %310 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 1
  %311 = getelementptr inbounds { i64, i64, i64 }, ptr %310, i32 0, i32 2
  %312 = load i64, ptr %311, align 8, !noundef !5
  %313 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_14, i32 0, i32 3
  store i64 %312, ptr %313, align 8
  %314 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %315 = getelementptr inbounds %Adt50, ptr %314, i32 0, i32 5
  %316 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %317 = getelementptr inbounds %Adt50, ptr %316, i32 0, i32 3
  %318 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %317, i32 0, i32 1
  %319 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %318, i32 0, i32 3
  %320 = load i32, ptr %319, align 4, !noundef !5
  %321 = getelementptr inbounds [7 x i32], ptr %315, i64 0, i64 0
  store i32 %320, ptr %321, align 8
  %322 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %323 = getelementptr inbounds %Adt50, ptr %322, i32 0, i32 3
  %324 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %323, i32 0, i32 1
  %325 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %324, i32 0, i32 3
  %326 = load i32, ptr %325, align 4, !noundef !5
  %327 = getelementptr inbounds [7 x i32], ptr %315, i64 0, i64 1
  store i32 %326, ptr %327, align 4
  %328 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %329 = getelementptr inbounds %Adt50, ptr %328, i32 0, i32 3
  %330 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %329, i32 0, i32 1
  %331 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %330, i32 0, i32 3
  %332 = load i32, ptr %331, align 4, !noundef !5
  %333 = getelementptr inbounds [7 x i32], ptr %315, i64 0, i64 2
  store i32 %332, ptr %333, align 8
  %334 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %335 = getelementptr inbounds %Adt50, ptr %334, i32 0, i32 3
  %336 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %335, i32 0, i32 1
  %337 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %336, i32 0, i32 3
  %338 = load i32, ptr %337, align 4, !noundef !5
  %339 = getelementptr inbounds [7 x i32], ptr %315, i64 0, i64 3
  store i32 %338, ptr %339, align 4
  %340 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %341 = getelementptr inbounds %Adt50, ptr %340, i32 0, i32 3
  %342 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %341, i32 0, i32 1
  %343 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %342, i32 0, i32 3
  %344 = load i32, ptr %343, align 4, !noundef !5
  %345 = getelementptr inbounds [7 x i32], ptr %315, i64 0, i64 4
  store i32 %344, ptr %345, align 8
  %346 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %347 = getelementptr inbounds %Adt50, ptr %346, i32 0, i32 3
  %348 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %347, i32 0, i32 1
  %349 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %348, i32 0, i32 3
  %350 = load i32, ptr %349, align 4, !noundef !5
  %351 = getelementptr inbounds [7 x i32], ptr %315, i64 0, i64 5
  store i32 %350, ptr %351, align 4
  %352 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %353 = getelementptr inbounds %Adt50, ptr %352, i32 0, i32 3
  %354 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %353, i32 0, i32 1
  %355 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %354, i32 0, i32 3
  %356 = load i32, ptr %355, align 4, !noundef !5
  %357 = getelementptr inbounds [7 x i32], ptr %315, i64 0, i64 6
  store i32 %356, ptr %357, align 8
  %358 = getelementptr inbounds %Adt50, ptr %_15, i32 0, i32 3
  %359 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %358, i32 0, i32 1
  %360 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %359, i32 0, i32 5
  %361 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %362 = getelementptr inbounds %Adt50, ptr %361, i32 0, i32 3
  %363 = load i128, ptr %362, align 16, !noundef !5
  store i128 %363, ptr %360, align 16
  %364 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %365 = getelementptr inbounds %Adt50, ptr %364, i32 0, i32 3
  %366 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %365, i32 0, i32 1
  %367 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %366, i32 0, i32 1
  %368 = load double, ptr %_7, align 8, !noundef !5
  store double %368, ptr %367, align 8
  %369 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %370 = getelementptr inbounds %Adt50, ptr %369, i32 0, i32 3
  %371 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %370, i32 0, i32 2
  %372 = load double, ptr %371, align 16, !noundef !5
  store double %372, ptr %_7, align 8
  %373 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 1
  %374 = load i8, ptr %373, align 2, !noundef !5
  switch i8 %374, label %bb4 [
    i8 0, label %bb1
    i8 84, label %bb5
  ]

bb5:                                              ; preds = %bb4
  %375 = getelementptr inbounds %Adt50, ptr %_15, i32 0, i32 3
  %376 = getelementptr inbounds { i128, { i64, double, i32, i32, [2 x i32], i128 }, double, [6 x i32] }, ptr %375, i32 0, i32 1
  %377 = getelementptr inbounds { i64, double, i32, i32, [2 x i32], i128 }, ptr %376, i32 0, i32 5
  %378 = load i128, ptr %377, align 16, !noundef !5
  store i128 %378, ptr %_5, align 16
  %379 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 1
  %380 = load i64, ptr %379, align 8, !noundef !5
  store i64 %380, ptr %_10, align 16
  %381 = load i8, ptr %_16, align 1, !range !6, !noundef !5
  %382 = trunc i8 %381 to i1
  %383 = getelementptr inbounds i8, ptr %_10, i64 8
  %384 = zext i1 %382 to i8
  store i8 %384, ptr %383, align 8
  %385 = load i64, ptr %_10, align 16, !noundef !5
  switch i64 %385, label %bb8 [
    i64 2, label %bb6
    i64 7564290096487423208, label %bb7
  ]

bb8:                                              ; preds = %bb7, %bb5
  ret void

bb6:                                              ; preds = %bb5
  %386 = getelementptr inbounds %Adt51, ptr %_10, i32 0, i32 2
  %387 = getelementptr inbounds %Adt50, ptr %386, i32 0, i32 1
  %388 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %387, i32 0, i32 1
  %389 = getelementptr inbounds { i16, i8, [5 x i8], i64 }, ptr %_1, i32 0, i32 1
  %390 = load i8, ptr %389, align 2, !noundef !5
  store i8 %390, ptr %388, align 2
  %391 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 1
  %392 = load i64, ptr %391, align 8, !noundef !5
  %393 = getelementptr inbounds { double, { i64, i64, i64 }, i16, i8, [5 x i8] }, ptr %_7, i32 0, i32 1
  %394 = load i64, ptr %393, align 8, !noundef !5
  %395 = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %392, i64 %394)
  %396 = extractvalue { i64, i1 } %395, 0
  %397 = extractvalue { i64, i1 } %395, 1
  store i64 %396, ptr %_10, align 16
  %398 = getelementptr inbounds i8, ptr %_10, i64 8
  %399 = zext i1 %397 to i8
  store i8 %399, ptr %398, align 8
  br label %bb3

bb7:                                              ; preds = %bb5
  %400 = load i128, ptr %_5, align 16, !noundef !5
; call _1851685_debug_2::bbox2
  call void @_ZN16_1851685_debug_25bbox217he0199f2e11de3e04E(i128 %400, ptr align 8 %_14)
  br label %bb8
}

; _1851685_debug_2::fn15
; Function Attrs: nonlazybind uwtable
define internal i128 @_ZN16_1851685_debug_24fn1517hfe3f07cbb5faefb0E() unnamed_addr #1 {
start:
  %_0 = alloca i128, align 16
  store i128 0, ptr %_0, align 16
; call core::hint::black_box
  call void @_ZN4core4hint9black_box17ha89c3f9cb79c398cE()
  %0 = load i128, ptr %_0, align 16, !noundef !5
  ret i128 %0
}

; _1851685_debug_2::main
; Function Attrs: nonlazybind uwtable
define internal void @_ZN16_1851685_debug_24main17he76cece459490d8aE() unnamed_addr #1 {
start:
; call _1851685_debug_2::enter
  call void @_ZN16_1851685_debug_25enter17h7e9cae7a334c5019E()
  ret void
}

; _1851685_debug_2::bbox2
; Function Attrs: noinline nonlazybind uwtable
define internal void @_ZN16_1851685_debug_25bbox217he0199f2e11de3e04E(i128 %val1, ptr align 8 %val2) unnamed_addr #0 {
start:
  %_6 = alloca { i16, i8, [5 x i8], i64 }, align 8
  %_5 = alloca { i16, i8, [5 x i8], i64 }, align 8
; call _1851685_debug_2::print_i128
  call void @_ZN16_1851685_debug_210print_i12817h036b4f930abaf46cE(i128 %val1)
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %_6, ptr align 8 %val2, i64 16, i1 false)
; call core::hint::black_box
  call void @_ZN4core4hint9black_box17h7d48bc7feb0af96eE(ptr sret({ i16, i8, [5 x i8], i64 }) align 8 %_5, ptr align 8 %_6)
  ret void
}

; _1851685_debug_2::print_i128
; Function Attrs: nonlazybind uwtable
define internal void @_ZN16_1851685_debug_210print_i12817h036b4f930abaf46cE(i128 %x) unnamed_addr #1 {
start:
  %_9 = lshr i128 %x, 64
  %_8 = trunc i128 %_9 to i64
  %_14 = trunc i128 %x to i64
  %_2 = call i32 (ptr, ...) @printf(ptr @alloc_2cdd8ac758b4c372b56d8683306290e0, i64 %_8, i64 %_14)
  ret void
}

; Function Attrs: nonlazybind uwtable
define i32 @rust_eh_personality(i32, i32, i64, ptr, ptr) unnamed_addr #1 {
start:
  ret i32 0
}

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #3

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #4

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare { i64, i1 } @llvm.ssub.with.overflow.i64(i64, i64) #5

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare { i64, i1 } @llvm.smul.with.overflow.i64(i64, i64) #5

; Function Attrs: nonlazybind uwtable
declare i32 @printf(ptr, ...) unnamed_addr #1

; Function Attrs: nonlazybind
define i32 @main(i32 %0, ptr %1) unnamed_addr #6 {
top:
  call void @_ZN16_1851685_debug_25enter17h7e9cae7a334c5019E()
  ret i32 0
}

attributes #0 = { noinline nonlazybind uwtable "probe-stack"="inline-asm" "target-cpu"="x86-64" }
attributes #1 = { nonlazybind uwtable "probe-stack"="inline-asm" "target-cpu"="x86-64" }
attributes #2 = { inlinehint nonlazybind uwtable "probe-stack"="inline-asm" "target-cpu"="x86-64" }
attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #4 = { nocallback nofree nounwind willreturn memory(argmem: write) }
attributes #5 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #6 = { nonlazybind "target-cpu"="x86-64" }

!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}

!0 = !{i32 8, !"PIC Level", i32 2}
!1 = !{i32 7, !"PIE Level", i32 2}
!2 = !{i32 2, !"RtLibUseGOT", i32 1}
!3 = !{!"rustc version 1.78.0-dev"}
!4 = !{i32 753499}
!5 = !{}
!6 = !{i8 0, i8 2}

```

Right:
```console
$ clang -O1 1851685_debug_2.ll && ./a.out
hi:-1 lo:-2580139605333929408
```

Wrong:
```console
$ clang -O2 1851685_debug_2.ll && ./a.out
hi:0 lo:-2580139605333929408
```

Bisects down to
```
BISECT: running pass (504) InstCombinePass on _ZN16_1851685_debug_25enter17h7e9cae7a334c5019E
```

Version:
```
clang version 19.0.0git (https://github.com/llvm/llvm-project.git cd1d4d8dd31f527615de26f5b62d687c6b2982a6)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/compiler-explorer/clang-trunk/bin
Compiler returned: 0
```

<details>
<summary>From Rust custom MIR</summary>

```rust
#![feature(custom_mir, core_intrinsics)]
extern crate core;
use core::intrinsics::mir::*;

pub fn enter() {
    fn14((0, 0, 0), [0; 6]);
}

#[custom_mir(dialect = "runtime", phase = "initial")]
pub fn fn14(mut _3: (i8, u16, isize), mut _6: [i32; 6]) {
    mir! {
    let _1: u128;
    let _2: i128;
    let _4: (i128,);
    let _5: i128;
    let _9: Adt59;
    let _11: isize;
    let _12: bool;
    let _13: Adt51;
    let _15: isize;
    let _16: Adt53;
    let _21: (i32, [i32; 6], (i8, u16, isize), [usize; 4]);
    let _23: (i8, u16, isize);
    let _25: Adt58;
    let _26: Adt52;
    let _44: ();
    {
    _2 = 0;
    _5 = 0;
    _3 = (84_i8, 40096_u16, (-9223372036854775808_isize));
    Goto(bb2)
    }
    bb1 = {
    Return()
    }
    bb2 = {
    _9.fld3.1.0.0 = 145713751_u32 as f64;
    _9.fld5 = _3.1 % 62066_u16;
    _13.fld1 = Checked(3029947793098001587_i64 - (-3638983068927244405_i64));
    _12 = _13.fld1.1 ^ _13.fld1.1;
    _9.fld6 = core::ptr::addr_of!(_13.fld1);
    _9.fld4 = (16948196345300582164_u64,);
    _13.fld3.fld4 = [168516996_i32,245529160_i32,1223136339_i32,1622354325_i32,(-1002348909_i32),1976405017_i32,(-1442509311_i32),1165829790_i32];
    _13.fld3.fld6.1 = -_9.fld3.1.0.0;
    _11 = !_3.2;
    _13.fld1 = (7564290096487423208_i64, _12);
    _13.fld3.fld6.2.0 = _11;
    _9.fld3.2.0 = _13.fld1.0;
    Call(_13.fld3.fld6.2.4 = fn15(), ReturnTo(bb3), UnwindUnreachable())
    }
    bb3 = {
    _13.fld0.0 = _9.fld3.2.0 as i16;
    _13.fld2 = _9.fld4.0 as isize;
    _13.fld3.fld5.1.0 = _13.fld3.fld6.2.4.0 >> _2;
    _9.fld3.1.0.0 = -_13.fld3.fld6.1;
    _13.fld0.2 = !_13.fld1.1;
    _13.fld3.fld5.3 = [_13.fld0.0];
    Goto(bb4)
    }
    bb4 = {
    _13.fld3.fld3.0 = _3.0;
    _6 = [(-154507050_i32),2086635898_i32,468582002_i32,(-21184342_i32),(-1173629817_i32),(-2078649110_i32)];
    _13.fld3.fld5.1.0 = _5;
    _16.fld0.2 = _13.fld0.2;
    _13.fld3.fld5.0 = _13.fld0.0 * _13.fld0.0;
    _9.fld2 = 2797771210_u32 + 2127377746_u32;
    _9.fld3.1.0.0 = _9.fld2 as f64;
    _15 = -_11;
    _13.fld0 = (_13.fld3.fld5.0, _13.fld3.fld5.1, _12, _13.fld3.fld5.3);
    _13.fld1 = Checked(_9.fld3.2.0 * _9.fld3.2.0);
    Goto(bb5)
    }
    bb5 = {
    _13.fld3.fld6.1 = _9.fld3.1.0.0 / 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012739273109665954_f64;
    _13.fld4 = !6496701646011298799_usize;
    _3 = (_13.fld3.fld3.0, _9.fld5, _15);
    _13.fld3.fld6.2.1 = _9.fld2;
    _13.fld0.2 = _13.fld0.1.0 >= _5;
    _13.fld3.fld3.2 = _3.2 & _11;
    _13.fld6 = [_13.fld0.2,_13.fld1.1,_16.fld0.2,_16.fld0.2,_13.fld0.2,_13.fld1.1];
    _13.fld3.fld6.2.4 = _13.fld3.fld5.1;
    _9.fld3.0 = -_13.fld0.0;
    _13.fld3.fld0 = core::ptr::addr_of!(_9.fld4.0);
    _9.fld0 = [_3.0];
    _13.fld5 = _13.fld3.fld4;
    _13.fld3.fld6.2.3 = _13.fld4 as i32;
    _3.2 = _13.fld3.fld3.2 ^ _13.fld3.fld6.2.0;
    _13.fld3.fld6.1 = _9.fld3.1.0.0;
    _23.0 = !_3.0;
    _13.fld3.fld3.1 = _13.fld1.1 as u16;
    _13.fld3.fld5.1.0 = _13.fld3.fld6.2.3 as i128;
    _13.fld3.fld6.2.3 = _13.fld3.fld3.1 as i32;
    Goto(bb7)
    }
    bb7 = {
    _23.0 = _13.fld3.fld6.2.3 as i8;
    _21.2 = (_23.0, _3.1, _13.fld3.fld3.2);
    _23.2 = _9.fld5 as isize;
    _13.fld3.fld6.0 = _13.fld1.0 as i128;
    _26.fld0 = _13.fld0.2 & _13.fld1.1;
    _9.fld3.2.2 = _3.2 ^ _23.2;
    _23 = (_21.2.0, _3.1, _9.fld3.2.2);
    _13.fld3.fld2 = [_13.fld3.fld6.2.3,_13.fld3.fld6.2.3,_13.fld3.fld6.2.3,_13.fld3.fld6.2.3,_13.fld3.fld6.2.3,_13.fld3.fld6.2.3,_13.fld3.fld6.2.3];
    _25.fld3.fld6.2.4 = (_13.fld3.fld6.0,);
    _13.fld3.fld6.2.2 = _9.fld3.1.0.0;
    _9.fld3.1.0.0 = _13.fld3.fld6.1;
    match _3.0 {
    0 => bb2,
    84 => bb10,
    _ => bb7
    }
    }
    bb10 = {
    _4 = (_25.fld3.fld6.2.4.0,);
    _13.fld1 = (_9.fld3.2.0, _26.fld0);
    match _13.fld1.0 {
    2 => bb14,
    7564290096487423208 => bb18,
    _ => bb19
    }
    }
    bb14 = {
    _13.fld3.fld3.0 = _3.0;
    _13.fld1 = Checked(_9.fld3.2.0 * _9.fld3.2.0);
    Goto(bb5)
    }
    bb18 = {
    Call(_44 = bbox2(_4, Move(_23)), ReturnTo(bb19), UnwindUnreachable())
    }
    bb19 = {
    Return()
    }

    }
}

#[custom_mir(dialect = "runtime", phase = "initial")]
fn fn15() -> (i128,) {
    mir! {
    let unit:();
    let _37: ();
    {
    RET = (0,);
    Call(_37 = core::hint::black_box(unit), ReturnTo(bb16), UnwindUnreachable())
    }
    bb16 = {
    Return()
    }

    }
}
pub fn main() {
    enter();
}

#[derive(Debug)]
pub struct Adt49 {}
#[derive(Debug)]
pub struct Adt50 {
    fld0: *const u64,
    fld2: [i32; 7],
    fld3: (i8, u16, isize),
    fld4: [i32; 8],
    fld5: (i16, (i128,), bool, [i16; 1]),
    fld6: (i128, f64, (isize, u32, f64, i32, (i128,)), [i32; 6]),
}
#[derive(Debug)]
pub struct Adt51 {
    fld0: (i16, (i128,), bool, [i16; 1]),
    fld1: (i64, bool),
    fld2: isize,
    fld3: Adt50,
    fld4: usize,
    fld5: [i32; 8],
    fld6: [bool; 6],
}
#[derive(Debug)]
pub struct Adt52 {
    fld0: bool,
}
#[derive(Debug)]
pub struct Adt53 {
    fld0: (i16, (i128,), bool, [i16; 1]),
}
#[derive(Debug)]
pub struct Adt58 {
    fld3: Adt50,
}
#[derive(Debug, Copy, Clone)]
pub struct Adt59 {
    fld0: [i8; 1],
    fld2: u32,
    fld3: (i16, ((f64,),), (i64, isize, isize), u8),
    fld4: (u64,),
    fld5: u16,
    fld6: *const (i64, bool),
}

#[inline(never)]
pub fn bbox2(val1: (i128,), val2: (i8, u16, isize)) {
    use core::hint::black_box;
    print_i128(val1.0);
    black_box(val2);
}

#[cfg(not(miri))]
fn print_i128(x: i128) {
    extern "C" {
        fn printf(fmt: *const core::ffi::c_char, ...) -> core::ffi::c_int;
    }
    unsafe {
        printf(
            b"hi:%ld lo:%ld\n\0".as_ptr().cast(),
            (x as u128 >> 64) as i64,
            x as i64,
        );
    }
}

#[cfg(miri)]
fn print_i128(x: i128) {
    println!("hi:{} lo:{}", (x as u128 >> 64) as i64, x as i64);
}

```

</details>

Reproducer: https://godbolt.org/z/xs1rhnMvb
Alive2: https://alive2.llvm.org/ce/z/gyL7mn

I will post a fix later.


commit 3c9022c965b85951f30af140da591f819acef8a0
Author: AdityaK <hiraditya@msn.com>
Date:   Tue Sep 10 22:39:02 2024 -0700

    Bail out jump threading on indirect branches (#103688)

    The bug was introduced by
    https://github.com/llvm/llvm-project/pull/68473

    Fixes: #102351

diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index d0669e44f821..c85c819263e2 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1028,7 +1028,14 @@ CanRedirectPredsOfEmptyBBToSucc(BasicBlock *BB, BasicBlock *Succ,
   if (!BB->hasNPredecessorsOrMore(2))
     return false;

-  // Get single common predecessors of both BB and Succ
+  if (any_of(BBPreds, [](const BasicBlock *Pred) {
+        return isa<PHINode>(Pred->begin()) &&
+               isa<IndirectBrInst>(Pred->getTerminator());
+      }))
+    return false;
+
+  // Get the single common predecessor of both BB and Succ. Return false
+  // when there are more than one common predecessors.
   for (BasicBlock *SuccPred : SuccPreds) {
     if (BBPreds.count(SuccPred)) {
       if (CommonPred)
@@ -1133,7 +1140,7 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,

   bool BBKillable = CanPropagatePredecessorsForPHIs(BB, Succ, BBPreds);

-  // Even if we can not fold bB into Succ, we may be able to redirect the
+  // Even if we can not fold BB into Succ, we may be able to redirect the
   // predecessors of BB to Succ.
   bool BBPhisMergeable =
       BBKillable ||

Miscompile in code with indirect gotos

The simplifycfg pass (incorrectly?) optimizes one of the case statements.

```llvm
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"
target triple = "x86_64-unknown-linux-gnu"

@.str = private unnamed_addr constant [23 x i8] c"OP_1:(instruction=%d)\0A\00", align 1
@.str.1 = private unnamed_addr constant [28 x i8] c"TERMINATE:(instruction=%d)\0A\00", align 1

; Function Attrs: mustprogress norecurse uwtable
define dso_local noundef i32 @main() #0 {
entry:
  %bytecode = alloca [2 x ptr], align 16
  store ptr blockaddress(@main, %VM__OP_1), ptr %bytecode, align 16, !tbaa !5
  %arrayidx1 = getelementptr inbounds [2 x ptr], ptr %bytecode, i64 0, i64 1
  store ptr blockaddress(@main, %VM__TERMINATE), ptr %arrayidx1, align 8, !tbaa !5
  br label %while.body

while.body:                                       ; preds = %entry, %sw.epilog
  %state.0 = phi i32 [ 0, %entry ], [ %state.1, %sw.epilog ]
  %index.0 = phi i32 [ 0, %entry ], [ %index.2, %sw.epilog ]
  switch i32 %state.0, label %sw.epilog [
    i32 0, label %sw.bb
    i32 1, label %VM__OP_1
    i32 2, label %sw.bb4
  ]

sw.bb:                                            ; preds = %while.body
  br label %indirectgoto

VM__OP_1:                                         ; preds = %while.body, %indirectgoto
  %index.1 = phi i32 [ %index.3, %indirectgoto ], [ %index.0, %while.body ]
  br label %sw.epilog

sw.bb4:                                           ; preds = %while.body
  %call = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 noundef %index.0)
  %inc = add nsw i32 %index.0, 1
  br label %indirectgoto

sw.epilog:                                        ; preds = %while.body, %VM__OP_1
  %state.1 = phi i32 [ %state.0, %while.body ], [ 2, %VM__OP_1 ]
  %index.2 = phi i32 [ %index.0, %while.body ], [ %index.1, %VM__OP_1 ]
  br label %while.body, !llvm.loop !9

VM__TERMINATE:                                    ; preds = %indirectgoto
  %call7 = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.1, i32 noundef %index.3)
  ret i32 0

indirectgoto:                                     ; preds = %sw.bb4, %sw.bb
  %index.3 = phi i32 [ %inc, %sw.bb4 ], [ %index.0, %sw.bb ]
  %idxprom.pn = sext i32 %index.3 to i64
  %indirect.goto.dest.in = getelementptr inbounds [2 x ptr], ptr %bytecode, i64 0, i64 %idxprom.pn
  %indirect.goto.dest = load ptr, ptr %indirect.goto.dest.in, align 8, !tbaa !5
  indirectbr ptr %indirect.goto.dest, [label %VM__OP_1, label %VM__TERMINATE]
}
declare i32 @printf(ptr noundef, ...) #1

attributes #0 = { mustprogress norecurse uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 18.0.0git (https://github.com/llvm/llvm-project.git 67782d2de5ea9c8653b8f0110237a3c355291c0e)"}
!5 = !{!6, !6, i64 0}
!6 = !{!"any pointer", !7, i64 0}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C++ TBAA"}
!9 = !{!10, !10, i64 0}
!10 = !{!"int", !7, i64 0}
!11 = distinct !{!11, !12, !13}
!12 = !{!"llvm.loop.mustprogress"}
!13 = !{!"llvm.loop.unroll.disable"}
```

$ opt -passes=simplifycfg orig.ll -S -o out.ll
```llvm
; ModuleID = 'orig.ll'
source_filename = "orig.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"
target triple = "x86_64-unknown-linux-gnu"

@.str = private unnamed_addr constant [23 x i8] c"OP_1:(instruction=%d)\0A\00", align 1
@.str.1 = private unnamed_addr constant [28 x i8] c"TERMINATE:(instruction=%d)\0A\00", align 1

; Function Attrs: mustprogress norecurse uwtable
define dso_local noundef i32 @main() #0 {
entry:
  %bytecode = alloca [2 x ptr], align 16
  store ptr blockaddress(@main, %VM__OP_1), ptr %bytecode, align 16, !tbaa !5
  %arrayidx1 = getelementptr inbounds [2 x ptr], ptr %bytecode, i64 0, i64 1
  store ptr blockaddress(@main, %VM__TERMINATE), ptr %arrayidx1, align 8, !tbaa !5
  br label %while.body

while.body:                                       ; preds = %sw.epilog, %entry
  %state.0 = phi i32 [ 0, %entry ], [ %state.1, %sw.epilog ]
  %index.0 = phi i32 [ 0, %entry ], [ %index.0, %sw.epilog ]
  switch i32 %state.0, label %sw.epilog [
    i32 0, label %VM__TERMINATE
    i32 1, label %VM__OP_1
    i32 2, label %sw.bb4
  ]

VM__OP_1:                                         ; preds = %while.body
  br label %sw.epilog

sw.bb4:                                           ; preds = %while.body
  %call = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 noundef %index.0)
  %inc = add nsw i32 %index.0, 1
  br label %VM__TERMINATE

sw.epilog:                                        ; preds = %VM__OP_1, %while.body
  %state.1 = phi i32 [ %state.0, %while.body ], [ 2, %VM__OP_1 ]
  br label %while.body, !llvm.loop !9

VM__TERMINATE:                                    ; preds = %sw.bb4, %while.body
  %index.3 = phi i32 [ %inc, %sw.bb4 ], [ %index.0, %while.body ]
  %call7 = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str.1, i32 noundef %index.3)
  ret i32 0
}

declare i32 @printf(ptr noundef, ...) #1

attributes #0 = { mustprogress norecurse uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 18.0.0git (https://github.com/llvm/llvm-project.git 67782d2de5ea9c8653b8f0110237a3c355291c0e)"}
!5 = !{!6, !6, i64 0}
!6 = !{!"any pointer", !7, i64 0}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C++ TBAA"}
!9 = !{!10, !10, i64 0}
!10 = !{!"int", !7, i64 0}
```

Original C code

```c
extern int printf(const char *fmt, ...);

int main() {
  void* bytecode[2];
  bytecode[0] = &&VM__OP_1;
  bytecode[1] = &&VM__TERMINATE;

  int state = 0;
  int index = 0;

  while (1) {
    switch (state) {
    case 0:
      goto *bytecode[index];
    case 1:
      // NOTE: THIS IS ONLY REACHABLE VIA INDIRECT GOTOS
      VM__OP_1:
      state = 2;
      break;
    case 2:
      printf("OP_1:(instruction=%d)\n", index);
      index++;
      goto *bytecode[index];
    }
  }

VM__TERMINATE:
  printf("TERMINATE:(instruction=%d)\n", index);
  return 0;
}
```

https://github.com/llvm/llvm-project/pull/76295 makes the miscompile go away(https://godbolt.org/z/d9bGnhhv6) but I think simplifycfg still has the bug.

Looks like TryToSimplifyUncondBranchFromEmptyBlock is not handling indirectbr predecessors correctly: the indirectbr's successor list is rewritten so it has a successor that isn't address-taken.  That edge is then proven impossible, so the indirectbr is completely eliminated.


commit bd8fe9972e3f17776e4e05e69e13ab8271d34132
Author: Florian Hahn <flo@fhahn.com>
Date:   Sat Sep 21 12:45:36 2024 +0100

    [VPlan] Mov licm to end of VPlan optimizations.

    This moves licm after expanding replicate regions. This fixes a crash
    when trying to hoist a predicated VPReplicateRecipes which later get
    expanded to replicate regions.

    Hoisting replicate regions out was not intended (see the discussion and
    at the review and comment on shallow traversal in licm()).

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

diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 06ac15f52fe1..fd6090affbbf 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -1158,7 +1158,6 @@ void VPlanTransforms::optimize(VPlan &Plan) {
   removeRedundantInductionCasts(Plan);

   simplifyRecipes(Plan);
-  licm(Plan);
   legalizeAndOptimizeInductions(Plan);
   removeDeadRecipes(Plan);

@@ -1166,6 +1165,7 @@ void VPlanTransforms::optimize(VPlan &Plan) {

   removeRedundantExpandSCEVRecipes(Plan);
   mergeBlocksIntoPredecessors(Plan);
+  licm(Plan);
 }

 // Add a VPActiveLaneMaskPHIRecipe and related recipes to \p Plan and replace

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

target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"
target triple = "arm64-apple-macosx14.0.0"

define i32 @test_invariant_replicate_region(i32 %x, i1 %c) {
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.latch

then:                                             ; preds = %loop.header
  %rem.1 = urem i32 10, %x
  br label %loop.latch

loop.latch:                                       ; preds = %then, %loop.header
  %res = phi i32 [ 0, %loop.header ], [ %rem.1, %then ]
  %iv.next = add i32 %iv, 1
  %ec = icmp eq i32 %iv, 99
  br i1 %ec, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret i32 %res
}

A/F: verifyVPlanIsValid(*Plan) && "VPlan is invalid" after a861ed411a

We have an internal test that recently started to hit an assertion failure which I bisected back to commit a861ed411a359b7cb2b58d642e4a7f2fdcf92057.

Consider the following code:
```c
int g_78, g_659, func_32_l_1852;
long g_128;
unsigned func_32_p_33;
void func_32() {
  int *l_1145 = &g_659;
  *l_1145 = 0;
  short __trans_tmp_11;
  for (; g_78; g_78 += 1) {
    func_32_l_1852 = 0;
    for (; func_32_l_1852 <= 3; func_32_l_1852 += 1) {
      int *l_1863 = &g_659;
      __trans_tmp_11 = *l_1863;
      if (10 % ((__trans_tmp_11 >= 0) - func_32_p_33))
        break;
      ++g_128;
      *l_1863 = func_32_p_33 <= --g_128;
    }
  }
}
```

If compiled with optimizations and a compiler built from a861ed411a359b7cb2b58d642e4a7f2fdcf92057 you can see it hits an assertion failure:
```
$ ~/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang -c -O2 repro.c
VPIRBasicBlock can only be used as pre-header or a successor of middle-block at the moment!
clang: /home/dyung/src/upstream/llvm_clean_git/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:8594: void llvm::LoopVectorizationPlanner::buildVPlansWithVPRecipes(llvm::ElementCount, llvm::ElementCount): Assertion `verifyVPlanIsValid(*Plan) && "VPlan is invalid"' 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/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang -c -O2 repro.c
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-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-verify-fixpoint>,loop-unroll<O2>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;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 "repro.c"
4.      Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "func_32"
 #0 0x00005572973a049f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x233549f)
 #1 0x000055729739dfec llvm::sys::CleanupOnSignal(unsigned long) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x2332fec)
 #2 0x00005572972f0418 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f5d2a347420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f5d29e1400b raise /build/glibc-LcI20x/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #5 0x00007f5d29df3859 abort /build/glibc-LcI20x/glibc-2.31/stdlib/abort.c:81:7
 #6 0x00007f5d29df3729 get_sysdep_segment_value /build/glibc-LcI20x/glibc-2.31/intl/loadmsgcat.c:509:8
 #7 0x00007f5d29df3729 _nl_load_domain /build/glibc-LcI20x/glibc-2.31/intl/loadmsgcat.c:970:34
 #8 0x00007f5d29e04fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #9 0x0000557298e08438 llvm::LoopVectorizationPlanner::buildVPlansWithVPRecipes(llvm::ElementCount, llvm::ElementCount) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x3d9d438)
#10 0x0000557298e0878f llvm::LoopVectorizationPlanner::plan(llvm::ElementCount, unsigned int) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x3d9d78f)
#11 0x0000557298e0a62e llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x3d9f62e)
#12 0x0000557298e0d501 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x3da2501)
#13 0x0000557298e0db73 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x3da2b73)
#14 0x0000557298836146 llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x37cb146)
#15 0x0000557296e5bd41 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x1df0d41)
#16 0x0000557295f84cc6 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/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0xf19cc6)
#17 0x0000557296e5a6ad llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x1def6ad)
#18 0x0000557295f85686 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0xf1a686)
#19 0x0000557296e5a0e1 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x1def0e1)
#20 0x0000557297636863 (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
#21 0x0000557297639dbd 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/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x25cedbd)
#22 0x0000557297d17c5c clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x2cacc5c)
#23 0x0000557299c7aa8c clang::ParseAST(clang::Sema&, bool, bool) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x4c0fa8c)
#24 0x0000557297d18078 clang::CodeGenAction::ExecuteAction() (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x2cad078)
#25 0x0000557297fdf129 clang::FrontendAction::Execute() (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x2f74129)
#26 0x0000557297f5b6fe clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x2ef06fe)
#27 0x00005572980cba26 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x3060a26)
#28 0x0000557295f09185 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0xe9e185)
#29 0x0000557295f00f0a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#30 0x0000557297d5e0cd 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
#31 0x00005572972f0920 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x2285920)
#32 0x0000557297d5e6ef 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
#33 0x0000557297d22274 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x2cb7274)
#34 0x0000557297d2338d clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x2cb838d)
#35 0x0000557297d2b4a5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0x2cc04a5)
#36 0x0000557295f0611b clang_main(int, char**, llvm::ToolContext const&) (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0xe9b11b)
#37 0x0000557295e3609b main (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0xdcb09b)
#38 0x00007f5d29df5083 __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c:342:3
#39 0x0000557295f0099e _start (/home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin/clang+0xe9599e)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 20.0.0 (https://github.com/llvm/llvm-project.git a861ed411a359b7cb2b58d642e4a7f2fdcf92057)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/dyung/src/upstream/a861ed411a359b7cb2b58d642e4a7f2fdcf92057-linux/bin
Build config: +assertions
```

Building with a compiler built from the commit that immediately preceded this one (37e5319a12ba47c18049728804d3d1e1b10c4eb4), you can see that the compilation succeeds.
```
$ ~/src/upstream/37e5319a12ba47c18049728804d3d1e1b10c4eb4-linux/bin/clang -c -O2 repro.c
$
```


commit 243ffbdf8b25285d04ee4393e86094312cb7c64f
Author: eaeltsin <109593613+eaeltsin@users.noreply.github.com>
Date:   Mon May 27 09:26:44 2024 +0200

    [DSE] Check write location in IsRedundantStore (#93400)

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

diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index ed4212d29cef..172cce2cfa38 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -2109,10 +2109,12 @@ struct DSEState {
         if (auto *MemSetI = dyn_cast<MemSetInst>(UpperInst)) {
           if (auto *SI = dyn_cast<StoreInst>(DefInst)) {
             // MemSetInst must have a write location.
-            MemoryLocation UpperLoc = *getLocForWrite(UpperInst);
+            auto UpperLoc = getLocForWrite(UpperInst);
+            if (!UpperLoc)
+              return false;
             int64_t InstWriteOffset = 0;
             int64_t DepWriteOffset = 0;
-            auto OR = isOverwrite(UpperInst, DefInst, UpperLoc, *MaybeDefLoc,
+            auto OR = isOverwrite(UpperInst, DefInst, *UpperLoc, *MaybeDefLoc,
                                   InstWriteOffset, DepWriteOffset);
             Value *StoredByte = isBytewiseValue(SI->getValueOperand(), DL);
             return StoredByte && StoredByte == MemSetI->getOperand(1) &&

opt < %s -aa-pipeline=basic-aa -passes=dse -S

target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #0

define void @test49() {
bb:
  call void @llvm.memset.p0.i64(ptr readonly null, i8 0, i64 0, i1 false)
  store ptr null, ptr null, align 8
  ret void
}

attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) }

[DSE] crash on applying * to std::nullopt

[reduced5.zip](https://github.com/llvm/llvm-project/files/15433764/reduced5.zip)

The command
```
opt -passes=dse reduced5.ll
```
fails occasionally. Debug version reliably complains
```
include/c++/v1/optional:805: assertion this->has_value() failed: optional operator* called on a disengaged value
```
with stack trace
```
    frame #3: 0x00005555663c6a43 opt`std::__u::optional<llvm::MemoryLocation>::operator*(this= Has Value=false ) && at optional:805:5
    frame #4: 0x00005555663c4d58 opt`(anonymous namespace)::DSEState::eliminateRedundantStoresOfExistingValues(this=0x00007fffffff9130)::'lambda'()::operator()() const at DeadStoreElimination.cpp:2119:39
    frame #5: 0x00005555663bf842 opt`(anonymous namespace)::DSEState::eliminateRedundantStoresOfExistingValues(this=0x00007fffffff9960) at DeadStoreElimination.cpp:2132:12
    frame #6: 0x00005555663b8956 opt`(anonymous namespace)::eliminateDeadStores(F=0x000033187fe3e008, AA=0x000033187feaafc8, MSSA=0x000033187fe603f0, DT=0x000033187fef6d78, PDT=0x000033187fed18d0, TLI=0x000033187fe0cd18, LI=0x000033187fe11cc8) at DeadStoreElimination.cpp:2332:23
    frame #7: 0x00005555663b6b3e opt`llvm::DSEPass::run(this=0x000033187fe08ad8, F=0x000033187fe3e008, AM=0x00007fffffffc1d8) at DeadStoreElimination.cpp:2355:18
```

The local fix is
```
==== llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp#184
# action=edit type=text
--- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp	2024-04-15 20:27:56.000000000 -0700
+++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp	2024-05-24 04:36:17.000000000 -0700
@@ -2109,10 +2109,12 @@
         if (auto *MemSetI = dyn_cast<MemSetInst>(UpperInst)) {
           if (auto *SI = dyn_cast<StoreInst>(DefInst)) {
             // MemSetInst must have a write location.
-            MemoryLocation UpperLoc = *getLocForWrite(UpperInst);
+            auto UpperLoc = getLocForWrite(UpperInst);
+            if (!UpperLoc)
+              return false;
             int64_t InstWriteOffset = 0;
             int64_t DepWriteOffset = 0;
-            auto OR = isOverwrite(UpperInst, DefInst, UpperLoc, *MaybeDefLoc,
+            auto OR = isOverwrite(UpperInst, DefInst, *UpperLoc, *MaybeDefLoc,
                                   InstWriteOffset, DepWriteOffset);
             Value *StoredByte = isBytewiseValue(SI->getValueOperand(), DL);
             return StoredByte && StoredByte == MemSetI->getOperand(1) &&
```
which basically reverts a piece of https://github.com/llvm/llvm-project/commit/81d69e1bda9e4b6a83f29ba1f614e43ab4700972

Looks like the actual problem happened earlier?

Please take a look, this is blocking us significantly.

@nikic @fhahn FYI

the reproducer was cooked by @alinas