[llvm] [Inliner] Keep nonnull information around when inlining (PR #185080)

Nikolas Klauser via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 15 02:10:18 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/185080

>From a9b14d296c5335d720a0fdb455930de11bdda6ab Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 10 Feb 2026 16:34:06 +0100
Subject: [PATCH 1/4] [Inliner] Keep nonnull information around when inlining

---
 .../Transforms/Utils/AssumeBundleBuilder.h    |  2 +
 .../InstCombine/InstCombineCalls.cpp          | 13 +++++-
 .../Transforms/Utils/AssumeBundleBuilder.cpp  | 27 +++++++++++
 llvm/lib/Transforms/Utils/InlineFunction.cpp  |  2 +-
 llvm/test/Transforms/Inline/cgscc-update.ll   |  2 +-
 llvm/test/Transforms/Inline/nonnull.ll        | 43 ++++++++++++++++--
 .../Inline/ret_attr_align_and_noundef.ll      |  9 ++++
 .../test/Transforms/Inline/ret_attr_update.ll |  4 ++
 llvm/test/Transforms/InstCombine/assume.ll    | 36 +++++++++++++++
 .../AArch64/hoist-runtime-checks.ll           | 45 +++++++++++--------
 .../X86/hoist-load-of-baseptr.ll              |  5 +++
 .../PhaseOrdering/loop-access-checks.ll       |  2 +
 12 files changed, 164 insertions(+), 26 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h b/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h
index eb91367dfdce0..f9d65d6b875ce 100644
--- a/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h
+++ b/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h
@@ -47,6 +47,8 @@ LLVM_ABI AssumeInst *buildAssumeFromInst(Instruction *I);
 LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC = nullptr,
                                DominatorTree *DT = nullptr);
 
+LLVM_ABI void salvageKnowledgeBeforeInlining(CallBase *CB, AssumptionCache *AC);
+
 /// Build and return a new assume created from the provided knowledge
 /// if the knowledge in the assume is fully redundant this will return nullptr
 LLVM_ABI AssumeInst *
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 8185f009bc9d0..1c99963b63170 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3710,7 +3710,18 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
           return CallBase::removeOperandBundle(II, OBU.getTagID());
         }
 
-        // TODO: apply nonnull return attributes to calls and invokes
+        // Fold the assume into a nonnull return attribute
+        // Note that we check the next node, since we care that the assume is
+        // valid after the CallBase, not before
+        // TODO: Fold nonnull into invokes
+        if (auto *CB = dyn_cast<CallBase>(RK.WasOn);
+            CB && !CB->isTerminator() &&
+            isValidAssumeForContext(II, CB->getNextNode(), &DT,
+                                    /*AllowEphemerals=*/true)) {
+          CB->addRetAttr(Attribute::NonNull);
+          Worklist.addValue(CB);
+          return CallBase::removeOperandBundle(II, OBU.getTagID());
+        }
       }
     }
 
diff --git a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
index 4aebeeda7f262..9befefd64c0f9 100644
--- a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
+++ b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
@@ -305,6 +305,33 @@ bool llvm::salvageKnowledge(Instruction *I, AssumptionCache *AC,
   return Changed;
 }
 
+void llvm::salvageKnowledgeBeforeInlining(CallBase *CB, AssumptionCache *AC) {
+  if (EnableKnowledgeRetention) {
+    salvageKnowledge(CB, AC);
+    return;
+  }
+
+  // TODO: Salvage knowledge from invokes
+  if (CB->isTerminator())
+    return;
+
+  SmallVector<OperandBundleDef, 1> AfterAttrs;
+  if (CB->hasRetAttr(Attribute::NonNull))
+    AfterAttrs.emplace_back("nonnull", CB);
+
+  if (AfterAttrs.empty())
+    return;
+
+  Module *M = CB->getModule();
+  Function *AssumeDecl =
+      Intrinsic::getOrInsertDeclaration(M, Intrinsic::assume);
+  AssumeInst *Assume = cast<AssumeInst>(CallInst::Create(
+      AssumeDecl, ConstantInt::getTrue(M->getContext()), AfterAttrs));
+  Assume->insertAfter(CB->getIterator());
+  if (AC)
+    AC->registerAssumption(Assume);
+}
+
 AssumeInst *
 llvm::buildAssumeFromKnowledge(ArrayRef<RetainedKnowledge> Knowledge,
                                Instruction *CtxI, AssumptionCache *AC,
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 3230b306f17d1..8a18875db779b 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -2718,7 +2718,7 @@ void llvm::InlineFunctionImpl(CallBase &CB, InlineFunctionInfo &IFI,
         IFI.GetAssumptionCache ? &IFI.GetAssumptionCache(*Caller) : nullptr;
 
     /// Preserve all attributes on of the call and its parameters.
-    salvageKnowledge(&CB, AC);
+    salvageKnowledgeBeforeInlining(&CB, AC);
 
     // We want the inliner to prune the code as it copies.  We would LOVE to
     // have no dead or constant instructions leftover after inlining occurs
diff --git a/llvm/test/Transforms/Inline/cgscc-update.ll b/llvm/test/Transforms/Inline/cgscc-update.ll
index f1121fa88a4b1..1f149a065ce2a 100644
--- a/llvm/test/Transforms/Inline/cgscc-update.ll
+++ b/llvm/test/Transforms/Inline/cgscc-update.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs,inline)' -S | FileCheck %s
+; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs,inline,instcombine)' -S | FileCheck %s
 ; This test runs the inliner and the function attribute deduction. It ensures
 ; that when the inliner mutates the call graph it correctly updates the CGSCC
 ; iteration so that we can compute refined function attributes. In this way it
diff --git a/llvm/test/Transforms/Inline/nonnull.ll b/llvm/test/Transforms/Inline/nonnull.ll
index 93aabfb6f10ab..4c8e16bccc90c 100644
--- a/llvm/test/Transforms/Inline/nonnull.ll
+++ b/llvm/test/Transforms/Inline/nonnull.ll
@@ -131,7 +131,7 @@ define void @caller6(ptr %arg) {
 declare ptr @buz()
 define nonnull ptr @callee7() {
 ; CHECK-LABEL: define nonnull ptr @callee7() {
-; CHECK-NEXT:    [[R:%.*]] = call ptr @buz() #[[ATTR0:[0-9]+]]
+; CHECK-NEXT:    [[R:%.*]] = call ptr @buz() #[[ATTR1:[0-9]+]]
 ; CHECK-NEXT:    ret ptr [[R]]
 ;
   %r = call ptr @buz() willreturn nounwind
@@ -140,7 +140,8 @@ define nonnull ptr @callee7() {
 
 define ptr @caller7() {
 ; CHECK-LABEL: define ptr @caller7() {
-; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @buz() #[[ATTR0]]
+; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @buz() #[[ATTR1]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
   %r = call ptr @callee7()
@@ -159,6 +160,7 @@ define nonnull ptr @callee8() {
 define ptr @caller8() {
 ; CHECK-LABEL: define ptr @caller8() {
 ; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @buz()
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee8()
@@ -168,7 +170,7 @@ define ptr @caller8() {
 define ptr @callee9() {
 ; CHECK-LABEL: define ptr @callee9() {
 ; CHECK-NEXT:    [[R:%.*]] = call ptr @buz()
-; CHECK-NEXT:    call void @foo() #[[ATTR1:[0-9]+]]
+; CHECK-NEXT:    call void @foo() #[[ATTR2:[0-9]+]]
 ; CHECK-NEXT:    ret ptr [[R]]
 ;
   %r = call ptr @buz()
@@ -179,9 +181,42 @@ define ptr @callee9() {
 define ptr @caller9() {
 ; CHECK-LABEL: define ptr @caller9() {
 ; CHECK-NEXT:    [[R_I:%.*]] = call ptr @buz()
-; CHECK-NEXT:    call void @foo() #[[ATTR1]]
+; CHECK-NEXT:    call void @foo() #[[ATTR2]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee9()
   ret ptr %r
 }
+
+declare i32 @__gxx_personality_v0(...)
+
+define ptr @simple_func(ptr %ptr) {
+; CHECK-LABEL: define ptr @simple_func
+; CHECK-SAME: (ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    ret ptr [[PTR]]
+;
+  ret ptr %ptr
+}
+
+define ptr @on_invoke() personality ptr @__gxx_personality_v0 {
+; CHECK-LABEL: define ptr @on_invoke() personality ptr @__gxx_personality_v0 {
+; CHECK-NEXT:    [[R:%.*]] = call ptr @buz()
+; CHECK-NEXT:    br label [[PROCEED:%.*]]
+; CHECK:       proceed:
+; CHECK-NEXT:    ret ptr [[R]]
+; CHECK:       pad:
+; CHECK-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT:            cleanup
+; CHECK-NEXT:    ret ptr [[R]]
+;
+  %r = call ptr @buz()
+  invoke nonnull ptr @simple_func(ptr %r) to label %proceed unwind label %pad
+
+proceed:
+  ret ptr %r
+
+pad:
+  landingpad { ptr, i32 } cleanup
+  ret ptr %r
+}
diff --git a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll
index c99d979be472b..0035e847ea0ef 100644
--- a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll
+++ b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll
@@ -188,6 +188,7 @@ define ptr @callee8() {
 define ptr @caller8_okay_use_after_poison_anyways() {
 ; CHECK-LABEL: define ptr @caller8_okay_use_after_poison_anyways() {
 ; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @foo()
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
@@ -208,6 +209,7 @@ define ptr @callee9() {
 define ptr @caller9_fail_creates_ub() {
 ; CHECK-LABEL: define ptr @caller9_fail_creates_ub() {
 ; CHECK-NEXT:    [[R_I:%.*]] = call noundef ptr @foo()
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
@@ -219,6 +221,7 @@ define ptr @caller9_fail_creates_ub() {
 define ptr @caller9_okay_is_ub_anyways() {
 ; CHECK-LABEL: define ptr @caller9_okay_is_ub_anyways() {
 ; CHECK-NEXT:    [[R_I:%.*]] = call noundef nonnull ptr @foo()
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
@@ -242,6 +245,7 @@ define ptr @caller10_fail_maybe_poison() {
 ; CHECK-LABEL: define ptr @caller10_fail_maybe_poison() {
 ; CHECK-NEXT:    [[R_I:%.*]] = call ptr @foo()
 ; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee10()
@@ -252,6 +256,7 @@ define ptr @caller10_okay_will_be_ub() {
 ; CHECK-LABEL: define ptr @caller10_okay_will_be_ub() {
 ; CHECK-NEXT:    [[R_I:%.*]] = call noundef nonnull ptr @foo()
 ; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
   %r = call noundef nonnull ptr @callee10()
@@ -262,6 +267,7 @@ define noundef ptr @caller10_okay_will_be_ub_todo() {
 ; CHECK-LABEL: define noundef ptr @caller10_okay_will_be_ub_todo() {
 ; CHECK-NEXT:    [[R_I:%.*]] = call ptr @foo()
 ; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee10()
@@ -306,6 +312,7 @@ define ptr @caller11_todo() {
 ; CHECK-NEXT:    [[COND2_I:%.*]] = call i1 @val()
 ; CHECK-NEXT:    br label [[CALLEE11_EXIT]]
 ; CHECK:       callee11.exit:
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee11()
@@ -333,6 +340,7 @@ define ptr @caller12_todo() {
 ; CHECK-NEXT:    [[COND_I:%.*]] = call i1 @val() #[[ATTR0]]
 ; CHECK-NEXT:    [[PP_I:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_I]], i64 -4)
 ; CHECK-NEXT:    [[R_I:%.*]] = select i1 [[COND_I]], ptr [[P_I]], ptr [[PP_I]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee12()
@@ -434,6 +442,7 @@ define ptr @caller_bad_ret_prop(ptr %p1, ptr %p2, i64 %x, ptr %other) {
 ; CHECK-NEXT:    br label [[CALLEE_BAD_RET_PROP_EXIT]]
 ; CHECK:       callee_bad_ret_prop.exit:
 ; CHECK-NEXT:    [[TMP2:%.*]] = phi ptr [ [[OTHER]], [[T_I]] ], [ [[TMP1]], [[F_I]] ]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP2]]) ]
 ; CHECK-NEXT:    ret ptr [[TMP2]]
 ;
   %1 = call noundef ptr %p1(i64 %x, ptr %p2)
diff --git a/llvm/test/Transforms/Inline/ret_attr_update.ll b/llvm/test/Transforms/Inline/ret_attr_update.ll
index 7004b5795125d..57d8c3b1f5932 100644
--- a/llvm/test/Transforms/Inline/ret_attr_update.ll
+++ b/llvm/test/Transforms/Inline/ret_attr_update.ll
@@ -17,6 +17,7 @@ define ptr @caller(ptr %ptr, i64 %x) {
 ; CHECK-LABEL: @caller(
 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[X:%.*]]
 ; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @foo(ptr noalias [[GEP]])
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
   %gep = getelementptr inbounds i8, ptr %ptr, i64 %x
@@ -54,6 +55,7 @@ define ptr @caller2(ptr %ptr, i64 %x, i1 %cond) {
 ; CHECK-NEXT:    [[R_I:%.*]] = call ptr @foo(ptr [[GEP]])
 ; CHECK-NEXT:    [[COND_I:%.*]] = icmp ne ptr [[R_I]], null
 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_I]]) [ "deopt"() ]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    [[R_I1:%.*]] = call ptr @bar(ptr [[GEP]])
 ; CHECK-NEXT:    [[COND_I2:%.*]] = icmp ne ptr [[R_I1]], null
 ; CHECK-NEXT:    br i1 [[COND_I2]], label [[RET_I:%.*]], label [[ORIG_I:%.*]]
@@ -63,6 +65,7 @@ define ptr @caller2(ptr %ptr, i64 %x, i1 %cond) {
 ; CHECK-NEXT:    br label [[CALLEE_WITH_EXPLICIT_CONTROL_FLOW_EXIT]]
 ; CHECK:       callee_with_explicit_control_flow.exit:
 ; CHECK-NEXT:    [[Q3:%.*]] = phi ptr [ [[R_I1]], [[RET_I]] ], [ [[GEP]], [[ORIG_I]] ]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[Q3]]) ]
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[PRET:%.*]], label [[QRET:%.*]]
 ; CHECK:       pret:
 ; CHECK-NEXT:    ret ptr [[R_I]]
@@ -187,6 +190,7 @@ define void @test7(ptr %ptr, i64 %x, i1 %cond) {
 ; CHECK-NEXT:    br label [[CALLEE7_EXIT]]
 ; CHECK:       callee7.exit:
 ; CHECK-NEXT:    [[T1:%.*]] = phi ptr [ [[R_I]], [[PASS_I]] ], [ [[S_I]], [[FAIL_I]] ]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[T1]]) ]
 ; CHECK-NEXT:    call void @snort(ptr [[T1]])
 ; CHECK-NEXT:    ret void
 ;
diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index 197d680babe11..f6a164895fa92 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -400,6 +400,42 @@ define i1 @nonnull5(ptr %a) {
   ret i1 %rval
 }
 
+declare ptr @get_ptr()
+
+define void @nonnull_on_call() {
+; CHECK-LABEL: @nonnull_on_call(
+; CHECK-NEXT:    [[PTR:%.*]] = call nonnull ptr @get_ptr()
+; CHECK-NEXT:    ret void
+;
+  %ptr = call ptr @get_ptr()
+  call void @llvm.assume(i1 true) [ "nonnull"(ptr %ptr) ]
+  ret void
+}
+
+declare i32 @__gxx_personality_v0(...)
+
+define void @nonnull_on_invoke() personality ptr @__gxx_personality_v0 {
+; CHECK-LABEL: @nonnull_on_invoke(
+; CHECK-NEXT:    [[PTR:%.*]] = invoke ptr @get_ptr()
+; CHECK-NEXT:            to label [[PROCEED:%.*]] unwind label [[PAD:%.*]]
+; CHECK:       proceed:
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[PTR]]) ]
+; CHECK-NEXT:    ret void
+; CHECK:       pad:
+; CHECK-NEXT:    [[TMP1:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT:            cleanup
+; CHECK-NEXT:    ret void
+;
+  %ptr = invoke ptr @get_ptr() to label %proceed unwind label %pad
+proceed:
+  call void @llvm.assume(i1 true) [ "nonnull"(ptr %ptr) ]
+  ret void
+
+pad:
+  landingpad { ptr, i32 } cleanup
+  ret void
+}
+
 define void @redundant_nonnull1(ptr nonnull %ptr) {
 ; CHECK-LABEL: @redundant_nonnull1(
 ; CHECK-NEXT:    ret void
diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-runtime-checks.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-runtime-checks.ll
index ed0452d8eccd5..0bcf989d1cf06 100644
--- a/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-runtime-checks.ll
+++ b/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-runtime-checks.ll
@@ -128,19 +128,22 @@ define dso_local noundef i32 @sum_prefix_with_sum(ptr %s.coerce0, i64 %s.coerce1
 ; CHECK-NEXT:    br i1 [[CMP5_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
 ; CHECK:       for.body.preheader:
 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[N]], -1
-; CHECK-NEXT:    [[DOTNOT_NOT:%.*]] = icmp ugt i64 [[S_COERCE1]], [[TMP0]]
-; CHECK-NEXT:    br i1 [[DOTNOT_NOT]], label [[FOR_BODY_PREHEADER8:%.*]], label [[COND_FALSE_I:%.*]], !prof [[PROF4:![0-9]+]]
-; CHECK:       for.body.preheader8:
-; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 8
+; CHECK-NEXT:    [[UMIN:%.*]] = tail call i64 @llvm.umin.i64(i64 [[S_COERCE1]], i64 [[TMP0]])
+; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[UMIN]], 1
+; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP6]], 9
 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY_PREHEADER11:%.*]], label [[VECTOR_PH:%.*]]
 ; CHECK:       vector.ph:
-; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -8
+; CHECK-NEXT:    [[N_MOD_VF:%.*]] = and i64 [[TMP6]], 7
+; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i64 [[N_MOD_VF]], 0
+; CHECK-NEXT:    [[TMP9:%.*]] = select i1 [[TMP8]], i64 8, i64 [[N_MOD_VF]]
+; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP6]], [[TMP9]]
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       vector.body:
 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[FOR_BODY]] ]
 ; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP3:%.*]], [[FOR_BODY]] ]
 ; CHECK-NEXT:    [[VEC_PHI9:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[FOR_BODY]] ]
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [4 x i8], ptr [[S_COERCE0]], i64 [[INDEX]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP1]]) ]
 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP1]], i64 16
 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4
 ; CHECK-NEXT:    [[WIDE_LOAD10:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4
@@ -148,31 +151,34 @@ define dso_local noundef i32 @sum_prefix_with_sum(ptr %s.coerce0, i64 %s.coerce1
 ; CHECK-NEXT:    [[TMP4]] = add <4 x i32> [[WIDE_LOAD10]], [[VEC_PHI9]]
 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
 ; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; CHECK-NEXT:    br i1 [[TMP5]], label [[SPAN_CHECKED_ACCESS_EXIT:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
+; CHECK-NEXT:    br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
 ; CHECK:       middle.block:
 ; CHECK-NEXT:    [[BIN_RDX:%.*]] = add <4 x i32> [[TMP4]], [[TMP3]]
 ; CHECK-NEXT:    [[ADD:%.*]] = tail call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[BIN_RDX]])
-; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
-; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY_PREHEADER11]]
+; CHECK-NEXT:    br label [[FOR_BODY_PREHEADER11]]
 ; CHECK:       for.body.preheader11:
-; CHECK-NEXT:    [[I_07_PH:%.*]] = phi i64 [ 0, [[FOR_BODY_PREHEADER8]] ], [ [[N_VEC]], [[SPAN_CHECKED_ACCESS_EXIT]] ]
-; CHECK-NEXT:    [[RET_0_LCSSA:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER8]] ], [ [[ADD]], [[SPAN_CHECKED_ACCESS_EXIT]] ]
+; CHECK-NEXT:    [[I_07_PH:%.*]] = phi i64 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[N_VEC]], [[MIDDLE_BLOCK]] ]
+; CHECK-NEXT:    [[RET_06_PH:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[ADD]], [[MIDDLE_BLOCK]] ]
 ; CHECK-NEXT:    br label [[FOR_BODY1:%.*]]
 ; CHECK:       for.cond.cleanup:
-; CHECK-NEXT:    [[RET_0_LCSSA1:%.*]] = phi i32 [ 0, [[ENTRY1:%.*]] ], [ [[ADD]], [[SPAN_CHECKED_ACCESS_EXIT]] ], [ [[ADD1:%.*]], [[FOR_BODY1]] ]
+; CHECK-NEXT:    [[RET_0_LCSSA1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD1:%.*]], [[SPAN_CHECKED_ACCESS_EXIT:%.*]] ]
 ; CHECK-NEXT:    ret i32 [[RET_0_LCSSA1]]
 ; CHECK:       for.body:
-; CHECK-NEXT:    [[I_07:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_BODY1]] ], [ [[I_07_PH]], [[FOR_BODY_PREHEADER11]] ]
-; CHECK-NEXT:    [[RET_06:%.*]] = phi i32 [ [[ADD1]], [[FOR_BODY1]] ], [ [[RET_0_LCSSA]], [[FOR_BODY_PREHEADER11]] ]
+; CHECK-NEXT:    [[I_07:%.*]] = phi i64 [ [[INC:%.*]], [[SPAN_CHECKED_ACCESS_EXIT]] ], [ [[I_07_PH]], [[FOR_BODY_PREHEADER11]] ]
+; CHECK-NEXT:    [[RET_06:%.*]] = phi i32 [ [[ADD1]], [[SPAN_CHECKED_ACCESS_EXIT]] ], [ [[RET_06_PH]], [[FOR_BODY_PREHEADER11]] ]
+; CHECK-NEXT:    [[EXITCOND_NOT1:%.*]] = icmp eq i64 [[I_07]], [[S_COERCE1]]
+; CHECK-NEXT:    br i1 [[EXITCOND_NOT1]], label [[COND_FALSE_I:%.*]], label [[SPAN_CHECKED_ACCESS_EXIT]], !prof [[PROF5:![0-9]+]]
+; CHECK:       cond.false.i:
+; CHECK-NEXT:    tail call void @llvm.trap()
+; CHECK-NEXT:    unreachable
+; CHECK:       span_checked_access.exit:
 ; CHECK-NEXT:    [[ARRAYIDX_I:%.*]] = getelementptr inbounds [4 x i8], ptr [[S_COERCE0]], i64 [[I_07]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARRAYIDX_I]]) ]
 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_I]], align 4
 ; CHECK-NEXT:    [[ADD1]] = add nsw i32 [[TMP7]], [[RET_06]]
 ; CHECK-NEXT:    [[INC]] = add nuw i64 [[I_07]], 1
 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY1]], !llvm.loop [[LOOP6:![0-9]+]]
-; CHECK:       cond.false.i:
-; CHECK-NEXT:    tail call void @llvm.trap()
-; CHECK-NEXT:    unreachable
 ;
 entry:
   %s = alloca %"class.std::__1::span", align 8
@@ -228,7 +234,7 @@ define hidden noundef nonnull align 4 dereferenceable(4) ptr @span_checked_acces
 ; CHECK-NEXT:    [[__SIZE__I:%.*]] = getelementptr inbounds nuw i8, ptr [[THIS]], i64 8
 ; CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr [[__SIZE__I]], align 8
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[__IDX]], [[TMP0]]
-; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]], !prof [[PROF4]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]], !prof [[PROF7:![0-9]+]]
 ; CHECK:       cond.false:
 ; CHECK-NEXT:    tail call void @llvm.trap()
 ; CHECK-NEXT:    unreachable
@@ -293,7 +299,8 @@ declare void @llvm.lifetime.end.p0(ptr nocapture)
 ; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
 ; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
 ; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
-; CHECK: [[PROF4]] = !{!"branch_weights", !"expected", i32 2000, i32 1}
-; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META1]], [[META2]]}
+; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
+; CHECK: [[PROF5]] = !{!"branch_weights", !"expected", i32 1, i32 2000}
 ; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META2]], [[META1]]}
+; CHECK: [[PROF7]] = !{!"branch_weights", !"expected", i32 2000, i32 1}
 ;.
diff --git a/llvm/test/Transforms/PhaseOrdering/X86/hoist-load-of-baseptr.ll b/llvm/test/Transforms/PhaseOrdering/X86/hoist-load-of-baseptr.ll
index 94766a1a83f7b..33b740f697c9a 100644
--- a/llvm/test/Transforms/PhaseOrdering/X86/hoist-load-of-baseptr.ll
+++ b/llvm/test/Transforms/PhaseOrdering/X86/hoist-load-of-baseptr.ll
@@ -32,6 +32,7 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O1:       [[FOR_BODY4]]:
 ; O1-NEXT:    [[J_05:%.*]] = phi i64 [ [[INC5:%.*]], %[[FOR_BODY4]] ], [ 0, %[[FOR_COND1_PREHEADER]] ]
 ; O1-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[J_05]]
+; O1-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I]]) ]
 ; O1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA2:![0-9]+]]
 ; O1-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP1]], 1
 ; O1-NEXT:    store i32 [[INC]], ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA2]]
@@ -56,6 +57,7 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O2:       [[VECTOR_BODY]]:
 ; O2-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ], [ 0, %[[FOR_BODY4_PREHEADER]] ]
 ; O2-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[INDEX]]
+; O2-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP1]]) ]
 ; O2-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP1]], i64 16
 ; O2-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4, !tbaa [[INT_TBAA0:![0-9]+]]
 ; O2-NEXT:    [[WIDE_LOAD8:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4, !tbaa [[INT_TBAA0]]
@@ -80,6 +82,7 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O2:       [[FOR_BODY4]]:
 ; O2-NEXT:    [[J_05:%.*]] = phi i64 [ [[INC5:%.*]], %[[FOR_BODY4]] ], [ [[J_05_PH]], %[[FOR_BODY4_PREHEADER9]] ]
 ; O2-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[J_05]]
+; O2-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I]]) ]
 ; O2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA0]]
 ; O2-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
 ; O2-NEXT:    store i32 [[INC]], ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA0]]
@@ -104,6 +107,7 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O3:       [[VECTOR_BODY]]:
 ; O3-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ], [ 0, %[[FOR_COND1_PREHEADER_US]] ]
 ; O3-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[INDEX]]
+; O3-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP1]]) ]
 ; O3-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP1]], i64 16
 ; O3-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4, !tbaa [[INT_TBAA0:![0-9]+]]
 ; O3-NEXT:    [[WIDE_LOAD9:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4, !tbaa [[INT_TBAA0]]
@@ -122,6 +126,7 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O3:       [[FOR_BODY4_US]]:
 ; O3-NEXT:    [[J_05_US:%.*]] = phi i64 [ [[INC5_US:%.*]], %[[FOR_BODY4_US]] ], [ [[J_05_US_PH]], %[[FOR_BODY4_US_PREHEADER]] ]
 ; O3-NEXT:    [[ADD_PTR_I_US:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[J_05_US]]
+; O3-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I_US]]) ]
 ; O3-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ADD_PTR_I_US]], align 4, !tbaa [[INT_TBAA0]]
 ; O3-NEXT:    [[INC_US:%.*]] = add nsw i32 [[TMP6]], 1
 ; O3-NEXT:    store i32 [[INC_US]], ptr [[ADD_PTR_I_US]], align 4, !tbaa [[INT_TBAA0]]
diff --git a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
index 3758140a20c4c..e11595bcbefc5 100644
--- a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
+++ b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
@@ -148,6 +148,7 @@ define void @foo(ptr noundef nonnull align 8 dereferenceable(24) noalias %vec) #
 ; CHECK:       [[FOR_BODY]]:
 ; CHECK-NEXT:    [[I_010:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP1]], i64 [[I_010]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I]]) ]
 ; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr [[ADD_PTR_I]], align 8
 ; CHECK-NEXT:    [[ADD:%.*]] = fadd double [[TMP2]], 1.000000e+00
 ; CHECK-NEXT:    store double [[ADD]], ptr [[ADD_PTR_I]], align 8
@@ -287,6 +288,7 @@ define void @loop_with_signed_induction(ptr noundef nonnull align 8 dereferencea
 ; CHECK:       [[FOR_BODY]]:
 ; CHECK-NEXT:    [[I_010:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds nuw [8 x i8], ptr [[TMP1]], i64 [[I_010]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I]]) ]
 ; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr [[ADD_PTR_I]], align 8, !tbaa [[DOUBLE_TBAA6:![0-9]+]]
 ; CHECK-NEXT:    [[ADD:%.*]] = fadd double [[TMP2]], 1.000000e+00
 ; CHECK-NEXT:    store double [[ADD]], ptr [[ADD_PTR_I]], align 8, !tbaa [[DOUBLE_TBAA6]]

>From 3b1d3485474a94d581c9d0226107c530fb67ea79 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 9 Jun 2026 22:18:15 +0200
Subject: [PATCH 2/4] Resolve remaining conflicts

---
 .../llvm/Transforms/Utils/AssumeBundleBuilder.h     | 10 ----------
 llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp   | 13 -------------
 2 files changed, 23 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h b/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h
index d10550e3f521b..083170bfbea3c 100644
--- a/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h
+++ b/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h
@@ -47,18 +47,8 @@ LLVM_ABI AssumeInst *buildAssumeFromInst(Instruction *I);
 LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC = nullptr,
                                DominatorTree *DT = nullptr);
 
-<<<<<<< HEAD
 LLVM_ABI void salvageKnowledgeBeforeInlining(CallBase *CB, AssumptionCache *AC);
 
-/// Build and return a new assume created from the provided knowledge
-/// if the knowledge in the assume is fully redundant this will return nullptr
-LLVM_ABI AssumeInst *
-buildAssumeFromKnowledge(ArrayRef<RetainedKnowledge> Knowledge,
-                         Instruction *CtxI, AssumptionCache *AC = nullptr,
-                         DominatorTree *DT = nullptr);
-
-=======
->>>>>>> main
 /// This pass attempts to minimize the number of assume without loosing any
 /// information.
 struct AssumeSimplifyPass : public OptionalPassInfoMixin<AssumeSimplifyPass> {
diff --git a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
index 08070aff2262d..6419836b41967 100644
--- a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
+++ b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
@@ -304,7 +304,6 @@ bool llvm::salvageKnowledge(Instruction *I, AssumptionCache *AC,
   return Changed;
 }
 
-<<<<<<< HEAD
 void llvm::salvageKnowledgeBeforeInlining(CallBase *CB, AssumptionCache *AC) {
   if (EnableKnowledgeRetention) {
     salvageKnowledge(CB, AC);
@@ -332,18 +331,6 @@ void llvm::salvageKnowledgeBeforeInlining(CallBase *CB, AssumptionCache *AC) {
     AC->registerAssumption(Assume);
 }
 
-AssumeInst *
-llvm::buildAssumeFromKnowledge(ArrayRef<RetainedKnowledge> Knowledge,
-                               Instruction *CtxI, AssumptionCache *AC,
-                               DominatorTree *DT) {
-  AssumeBuilderState Builder(CtxI->getModule(), CtxI, AC, DT);
-  for (const RetainedKnowledge &RK : Knowledge)
-    Builder.addKnowledge(RK);
-  return Builder.build();
-}
-
-=======
->>>>>>> main
 RetainedKnowledge llvm::simplifyRetainedKnowledge(AssumeInst *Assume,
                                                   RetainedKnowledge RK,
                                                   AssumptionCache *AC,

>From 15c75b7ecab74f35d59660e790ba4186ce2a0091 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 9 Jun 2026 23:13:20 +0200
Subject: [PATCH 3/4] Fix tests

---
 llvm/test/Transforms/InstCombine/assume.ll    |   2 -
 .../AArch64/hoist-runtime-checks.ll           |   4 +-
 .../X86/hoist-load-of-baseptr.ll              | 112 +++++++++---------
 .../PhaseOrdering/loop-access-checks.ll       |  24 ++--
 4 files changed, 71 insertions(+), 71 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index d32dfaacada8c..0dab2b2004ea7 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -532,8 +532,6 @@ define i1 @nonnull5(ptr %a) {
   ret i1 %rval
 }
 
-declare ptr @get_ptr()
-
 define void @nonnull_on_call() {
 ; CHECK-LABEL: @nonnull_on_call(
 ; CHECK-NEXT:    [[PTR:%.*]] = call nonnull ptr @get_ptr()
diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-runtime-checks.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-runtime-checks.ll
index 99e68937ce21c..969994567697f 100644
--- a/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-runtime-checks.ll
+++ b/llvm/test/Transforms/PhaseOrdering/AArch64/hoist-runtime-checks.ll
@@ -137,13 +137,13 @@ define dso_local noundef i32 @sum_prefix_with_sum(ptr %s.coerce0, i64 %s.coerce1
 ; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i64 [[N_MOD_VF]], 0
 ; CHECK-NEXT:    [[TMP9:%.*]] = select i1 [[TMP8]], i64 8, i64 [[N_MOD_VF]]
 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[TMP6]], [[TMP9]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[S_COERCE0]]) ]
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       vector.body:
 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[FOR_BODY]] ]
 ; CHECK-NEXT:    [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP3:%.*]], [[FOR_BODY]] ]
 ; CHECK-NEXT:    [[VEC_PHI9:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[FOR_BODY]] ]
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [4 x i8], ptr [[S_COERCE0]], i64 [[INDEX]]
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP1]]) ]
 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP1]], i64 16
 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4
 ; CHECK-NEXT:    [[WIDE_LOAD10:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4
@@ -173,7 +173,7 @@ define dso_local noundef i32 @sum_prefix_with_sum(ptr %s.coerce0, i64 %s.coerce1
 ; CHECK-NEXT:    unreachable
 ; CHECK:       span_checked_access.exit:
 ; CHECK-NEXT:    [[ARRAYIDX_I:%.*]] = getelementptr inbounds [4 x i8], ptr [[S_COERCE0]], i64 [[I_07]]
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ARRAYIDX_I]]) ]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[S_COERCE0]]) ]
 ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX_I]], align 4
 ; CHECK-NEXT:    [[ADD1]] = add nsw i32 [[TMP7]], [[RET_06]]
 ; CHECK-NEXT:    [[INC]] = add nuw i64 [[I_07]], 1
diff --git a/llvm/test/Transforms/PhaseOrdering/X86/hoist-load-of-baseptr.ll b/llvm/test/Transforms/PhaseOrdering/X86/hoist-load-of-baseptr.ll
index c4e9baa17804d..f8b855b357b81 100644
--- a/llvm/test/Transforms/PhaseOrdering/X86/hoist-load-of-baseptr.ll
+++ b/llvm/test/Transforms/PhaseOrdering/X86/hoist-load-of-baseptr.ll
@@ -18,7 +18,7 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O1-SAME: ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(24) [[DATA:%.*]], i64 noundef [[NUMELEMS:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
 ; O1-NEXT:  [[ENTRY:.*]]:
 ; O1-NEXT:    [[CMP24_NOT:%.*]] = icmp eq i64 [[NUMELEMS]], 0
-; O1-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DATA]], align 8
+; O1-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DATA]], align 8, !nonnull [[META0:![0-9]+]]
 ; O1-NEXT:    br label %[[FOR_COND1_PREHEADER:.*]]
 ; O1:       [[FOR_COND1_PREHEADER]]:
 ; O1-NEXT:    [[I_06:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[INC7:%.*]], %[[FOR_COND_CLEANUP3:.*]] ]
@@ -28,23 +28,22 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O1:       [[FOR_COND_CLEANUP3]]:
 ; O1-NEXT:    [[INC7]] = add nuw nsw i64 [[I_06]], 1
 ; O1-NEXT:    [[EXITCOND7_NOT:%.*]] = icmp eq i64 [[INC7]], 100
-; O1-NEXT:    br i1 [[EXITCOND7_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_COND1_PREHEADER]], !llvm.loop [[LOOP0:![0-9]+]]
+; O1-NEXT:    br i1 [[EXITCOND7_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_COND1_PREHEADER]], !llvm.loop [[LOOP1:![0-9]+]]
 ; O1:       [[FOR_BODY4]]:
 ; O1-NEXT:    [[J_05:%.*]] = phi i64 [ [[INC5:%.*]], %[[FOR_BODY4]] ], [ 0, %[[FOR_COND1_PREHEADER]] ]
 ; O1-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[J_05]]
-; O1-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I]]) ]
-; O1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA2:![0-9]+]]
+; O1-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA3:![0-9]+]]
 ; O1-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP1]], 1
-; O1-NEXT:    store i32 [[INC]], ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA2]]
+; O1-NEXT:    store i32 [[INC]], ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA3]]
 ; O1-NEXT:    [[INC5]] = add nuw i64 [[J_05]], 1
 ; O1-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC5]], [[NUMELEMS]]
-; O1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP3]], label %[[FOR_BODY4]], !llvm.loop [[LOOP6:![0-9]+]]
+; O1-NEXT:    br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP3]], label %[[FOR_BODY4]], !llvm.loop [[LOOP7:![0-9]+]]
 ;
 ; O2-LABEL: define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(
 ; O2-SAME: ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(24) [[DATA:%.*]], i64 noundef [[NUMELEMS:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
 ; O2-NEXT:  [[ENTRY:.*]]:
 ; O2-NEXT:    [[CMP24_NOT:%.*]] = icmp eq i64 [[NUMELEMS]], 0
-; O2-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DATA]], align 8
+; O2-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DATA]], align 8, !nonnull [[META0:![0-9]+]]
 ; O2-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[NUMELEMS]], 8
 ; O2-NEXT:    [[N_VEC:%.*]] = and i64 [[NUMELEMS]], -8
 ; O2-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[NUMELEMS]], [[N_VEC]]
@@ -57,17 +56,16 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O2:       [[VECTOR_BODY]]:
 ; O2-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ], [ 0, %[[FOR_BODY4_PREHEADER]] ]
 ; O2-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[INDEX]]
-; O2-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP1]]) ]
 ; O2-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP1]], i64 16
-; O2-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4, !tbaa [[INT_TBAA0:![0-9]+]]
-; O2-NEXT:    [[WIDE_LOAD8:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4, !tbaa [[INT_TBAA0]]
+; O2-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4, !tbaa [[INT_TBAA1:![0-9]+]]
+; O2-NEXT:    [[WIDE_LOAD8:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4, !tbaa [[INT_TBAA1]]
 ; O2-NEXT:    [[TMP3:%.*]] = add nsw <4 x i32> [[WIDE_LOAD]], splat (i32 1)
 ; O2-NEXT:    [[TMP4:%.*]] = add nsw <4 x i32> [[WIDE_LOAD8]], splat (i32 1)
-; O2-NEXT:    store <4 x i32> [[TMP3]], ptr [[TMP1]], align 4, !tbaa [[INT_TBAA0]]
-; O2-NEXT:    store <4 x i32> [[TMP4]], ptr [[TMP2]], align 4, !tbaa [[INT_TBAA0]]
+; O2-NEXT:    store <4 x i32> [[TMP3]], ptr [[TMP1]], align 4, !tbaa [[INT_TBAA1]]
+; O2-NEXT:    store <4 x i32> [[TMP4]], ptr [[TMP2]], align 4, !tbaa [[INT_TBAA1]]
 ; O2-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
 ; O2-NEXT:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; O2-NEXT:    br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
+; O2-NEXT:    br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
 ; O2:       [[MIDDLE_BLOCK]]:
 ; O2-NEXT:    br i1 [[CMP_N]], label %[[FOR_COND_CLEANUP3]], label %[[FOR_BODY4_PREHEADER9]]
 ; O2:       [[FOR_BODY4_PREHEADER9]]:
@@ -78,23 +76,22 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O2:       [[FOR_COND_CLEANUP3]]:
 ; O2-NEXT:    [[INC7]] = add nuw nsw i64 [[I_06]], 1
 ; O2-NEXT:    [[EXITCOND7_NOT:%.*]] = icmp eq i64 [[INC7]], 100
-; O2-NEXT:    br i1 [[EXITCOND7_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_COND1_PREHEADER]], !llvm.loop [[LOOP8:![0-9]+]]
+; O2-NEXT:    br i1 [[EXITCOND7_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_COND1_PREHEADER]], !llvm.loop [[LOOP9:![0-9]+]]
 ; O2:       [[FOR_BODY4]]:
 ; O2-NEXT:    [[J_05:%.*]] = phi i64 [ [[INC5:%.*]], %[[FOR_BODY4]] ], [ [[J_05_PH]], %[[FOR_BODY4_PREHEADER9]] ]
 ; O2-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[J_05]]
-; O2-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I]]) ]
-; O2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA0]]
+; O2-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA1]]
 ; O2-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP6]], 1
-; O2-NEXT:    store i32 [[INC]], ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA0]]
+; O2-NEXT:    store i32 [[INC]], ptr [[ADD_PTR_I]], align 4, !tbaa [[INT_TBAA1]]
 ; O2-NEXT:    [[INC5]] = add nuw i64 [[J_05]], 1
 ; O2-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC5]], [[NUMELEMS]]
-; O2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP3]], label %[[FOR_BODY4]], !llvm.loop [[LOOP9:![0-9]+]]
+; O2-NEXT:    br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP3]], label %[[FOR_BODY4]], !llvm.loop [[LOOP10:![0-9]+]]
 ;
 ; O3-LABEL: define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(
 ; O3-SAME: ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(24) [[DATA:%.*]], i64 noundef [[NUMELEMS:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
 ; O3-NEXT:  [[ENTRY:.*:]]
 ; O3-NEXT:    [[CMP24_NOT:%.*]] = icmp eq i64 [[NUMELEMS]], 0
-; O3-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DATA]], align 8
+; O3-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[DATA]], align 8, !nonnull [[META0:![0-9]+]]
 ; O3-NEXT:    br i1 [[CMP24_NOT]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_COND1_PREHEADER_US_PREHEADER:.*]]
 ; O3:       [[FOR_COND1_PREHEADER_US_PREHEADER]]:
 ; O3-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[NUMELEMS]], 8
@@ -107,17 +104,16 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O3:       [[VECTOR_BODY]]:
 ; O3-NEXT:    [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ], [ 0, %[[FOR_COND1_PREHEADER_US]] ]
 ; O3-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[INDEX]]
-; O3-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP1]]) ]
 ; O3-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP1]], i64 16
-; O3-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4, !tbaa [[INT_TBAA0:![0-9]+]]
-; O3-NEXT:    [[WIDE_LOAD9:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4, !tbaa [[INT_TBAA0]]
+; O3-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i32>, ptr [[TMP1]], align 4, !tbaa [[INT_TBAA1:![0-9]+]]
+; O3-NEXT:    [[WIDE_LOAD9:%.*]] = load <4 x i32>, ptr [[TMP2]], align 4, !tbaa [[INT_TBAA1]]
 ; O3-NEXT:    [[TMP3:%.*]] = add nsw <4 x i32> [[WIDE_LOAD]], splat (i32 1)
 ; O3-NEXT:    [[TMP4:%.*]] = add nsw <4 x i32> [[WIDE_LOAD9]], splat (i32 1)
-; O3-NEXT:    store <4 x i32> [[TMP3]], ptr [[TMP1]], align 4, !tbaa [[INT_TBAA0]]
-; O3-NEXT:    store <4 x i32> [[TMP4]], ptr [[TMP2]], align 4, !tbaa [[INT_TBAA0]]
+; O3-NEXT:    store <4 x i32> [[TMP3]], ptr [[TMP1]], align 4, !tbaa [[INT_TBAA1]]
+; O3-NEXT:    store <4 x i32> [[TMP4]], ptr [[TMP2]], align 4, !tbaa [[INT_TBAA1]]
 ; O3-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
 ; O3-NEXT:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
-; O3-NEXT:    br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
+; O3-NEXT:    br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
 ; O3:       [[MIDDLE_BLOCK]]:
 ; O3-NEXT:    br i1 [[CMP_N]], label %[[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]], label %[[FOR_BODY4_US_PREHEADER]]
 ; O3:       [[FOR_BODY4_US_PREHEADER]]:
@@ -126,17 +122,16 @@ define dso_local void @_Z7computeRSt6vectorIiSaIiEEy(ptr noundef nonnull align 8
 ; O3:       [[FOR_BODY4_US]]:
 ; O3-NEXT:    [[J_05_US:%.*]] = phi i64 [ [[INC5_US:%.*]], %[[FOR_BODY4_US]] ], [ [[J_05_US_PH]], %[[FOR_BODY4_US_PREHEADER]] ]
 ; O3-NEXT:    [[ADD_PTR_I_US:%.*]] = getelementptr inbounds [4 x i8], ptr [[TMP0]], i64 [[J_05_US]]
-; O3-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I_US]]) ]
-; O3-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ADD_PTR_I_US]], align 4, !tbaa [[INT_TBAA0]]
+; O3-NEXT:    [[TMP6:%.*]] = load i32, ptr [[ADD_PTR_I_US]], align 4, !tbaa [[INT_TBAA1]]
 ; O3-NEXT:    [[INC_US:%.*]] = add nsw i32 [[TMP6]], 1
-; O3-NEXT:    store i32 [[INC_US]], ptr [[ADD_PTR_I_US]], align 4, !tbaa [[INT_TBAA0]]
+; O3-NEXT:    store i32 [[INC_US]], ptr [[ADD_PTR_I_US]], align 4, !tbaa [[INT_TBAA1]]
 ; O3-NEXT:    [[INC5_US]] = add nuw i64 [[J_05_US]], 1
 ; O3-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC5_US]], [[NUMELEMS]]
-; O3-NEXT:    br i1 [[EXITCOND_NOT]], label %[[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]], label %[[FOR_BODY4_US]], !llvm.loop [[LOOP8:![0-9]+]]
+; O3-NEXT:    br i1 [[EXITCOND_NOT]], label %[[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]], label %[[FOR_BODY4_US]], !llvm.loop [[LOOP9:![0-9]+]]
 ; O3:       [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]:
 ; O3-NEXT:    [[INC7_US]] = add nuw nsw i64 [[I_06_US]], 1
 ; O3-NEXT:    [[EXITCOND8_NOT:%.*]] = icmp eq i64 [[INC7_US]], 100
-; O3-NEXT:    br i1 [[EXITCOND8_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_COND1_PREHEADER_US]], !llvm.loop [[LOOP9:![0-9]+]]
+; O3-NEXT:    br i1 [[EXITCOND8_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_COND1_PREHEADER_US]], !llvm.loop [[LOOP10:![0-9]+]]
 ; O3:       [[FOR_COND_CLEANUP]]:
 ; O3-NEXT:    ret void
 ;
@@ -243,33 +238,36 @@ declare void @llvm.lifetime.end.p0(ptr nocapture)
 !16 = !{!17, !4, i64 0}
 !17 = !{!"_ZTSNSt12_Vector_baseIiSaIiEE17_Vector_impl_dataE", !4, i64 0, !4, i64 8, !4, i64 16}
 ;.
-; O1: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]]}
-; O1: [[META1]] = !{!"llvm.loop.mustprogress"}
-; O1: [[INT_TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0}
-; O1: [[META3]] = !{!"int", [[META4:![0-9]+]], i64 0}
-; O1: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
-; O1: [[META5]] = !{!"Simple C++ TBAA"}
-; O1: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]]}
+; O1: [[META0]] = !{}
+; O1: [[LOOP1]] = distinct !{[[LOOP1]], [[META2:![0-9]+]]}
+; O1: [[META2]] = !{!"llvm.loop.mustprogress"}
+; O1: [[INT_TBAA3]] = !{[[META4:![0-9]+]], [[META4]], i64 0}
+; O1: [[META4]] = !{!"int", [[META5:![0-9]+]], i64 0}
+; O1: [[META5]] = !{!"omnipotent char", [[META6:![0-9]+]], i64 0}
+; O1: [[META6]] = !{!"Simple C++ TBAA"}
+; O1: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]]}
 ;.
-; O2: [[INT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
-; O2: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0}
-; O2: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
-; O2: [[META3]] = !{!"Simple C++ TBAA"}
-; O2: [[LOOP4]] = distinct !{[[LOOP4]], [[META5:![0-9]+]], [[META6:![0-9]+]], [[META7:![0-9]+]]}
-; O2: [[META5]] = !{!"llvm.loop.mustprogress"}
-; O2: [[META6]] = !{!"llvm.loop.isvectorized", i32 1}
-; O2: [[META7]] = !{!"llvm.loop.unroll.runtime.disable"}
-; O2: [[LOOP8]] = distinct !{[[LOOP8]], [[META5]]}
-; O2: [[LOOP9]] = distinct !{[[LOOP9]], [[META5]], [[META7]], [[META6]]}
+; O2: [[META0]] = !{}
+; O2: [[INT_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0}
+; O2: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0}
+; O2: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
+; O2: [[META4]] = !{!"Simple C++ TBAA"}
+; O2: [[LOOP5]] = distinct !{[[LOOP5]], [[META6:![0-9]+]], [[META7:![0-9]+]], [[META8:![0-9]+]]}
+; O2: [[META6]] = !{!"llvm.loop.mustprogress"}
+; O2: [[META7]] = !{!"llvm.loop.isvectorized", i32 1}
+; O2: [[META8]] = !{!"llvm.loop.unroll.runtime.disable"}
+; O2: [[LOOP9]] = distinct !{[[LOOP9]], [[META6]]}
+; O2: [[LOOP10]] = distinct !{[[LOOP10]], [[META6]], [[META8]], [[META7]]}
 ;.
-; O3: [[INT_TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
-; O3: [[META1]] = !{!"int", [[META2:![0-9]+]], i64 0}
-; O3: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
-; O3: [[META3]] = !{!"Simple C++ TBAA"}
-; O3: [[LOOP4]] = distinct !{[[LOOP4]], [[META5:![0-9]+]], [[META6:![0-9]+]], [[META7:![0-9]+]]}
-; O3: [[META5]] = !{!"llvm.loop.mustprogress"}
-; O3: [[META6]] = !{!"llvm.loop.isvectorized", i32 1}
-; O3: [[META7]] = !{!"llvm.loop.unroll.runtime.disable"}
-; O3: [[LOOP8]] = distinct !{[[LOOP8]], [[META5]], [[META7]], [[META6]]}
-; O3: [[LOOP9]] = distinct !{[[LOOP9]], [[META5]]}
+; O3: [[META0]] = !{}
+; O3: [[INT_TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0}
+; O3: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0}
+; O3: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
+; O3: [[META4]] = !{!"Simple C++ TBAA"}
+; O3: [[LOOP5]] = distinct !{[[LOOP5]], [[META6:![0-9]+]], [[META7:![0-9]+]], [[META8:![0-9]+]]}
+; O3: [[META6]] = !{!"llvm.loop.mustprogress"}
+; O3: [[META7]] = !{!"llvm.loop.isvectorized", i32 1}
+; O3: [[META8]] = !{!"llvm.loop.unroll.runtime.disable"}
+; O3: [[LOOP9]] = distinct !{[[LOOP9]], [[META6]], [[META8]], [[META7]]}
+; O3: [[LOOP10]] = distinct !{[[LOOP10]], [[META6]]}
 ;.
diff --git a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
index c68b0ab42f950..1fac45de700a5 100644
--- a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
+++ b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
@@ -133,7 +133,7 @@ declare void @llvm.lifetime.end.p0(ptr nocapture)
 define void @foo(ptr noundef nonnull align 8 dereferenceable(24) noalias %vec) #0 {
 ; CHECK-LABEL: define void @foo(
 ; CHECK-SAME: ptr noalias nofree noundef nonnull readonly align 8 captures(none) dereferenceable(24) [[VEC:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:  [[ENTRY:.*:]]
 ; CHECK-NEXT:    [[_M_FINISH_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 8
 ; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[_M_FINISH_I_I]], align 8, !tbaa [[ANYPTR_TBAA0:![0-9]+]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[VEC]], align 8, !tbaa [[ANYPTR_TBAA5:![0-9]+]]
@@ -143,18 +143,20 @@ define void @foo(ptr noundef nonnull align 8 dereferenceable(24) noalias %vec) #
 ; CHECK-NEXT:    [[SUB_PTR_DIV_I_I:%.*]] = ashr exact i64 [[SUB_PTR_SUB_I_I]], 3
 ; CHECK-NEXT:    [[CMP_NOT9:%.*]] = icmp eq ptr [[TMP0]], [[TMP1]]
 ; CHECK-NEXT:    br i1 [[CMP_NOT9]], label %[[FOR_COND_CLEANUP:.*]], label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP1]]) ]
+; CHECK-NEXT:    br label %[[FOR_BODY1:.*]]
 ; CHECK:       [[FOR_COND_CLEANUP]]:
 ; CHECK-NEXT:    ret void
-; CHECK:       [[FOR_BODY]]:
-; CHECK-NEXT:    [[I_010:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
+; CHECK:       [[FOR_BODY1]]:
+; CHECK-NEXT:    [[I_010:%.*]] = phi i64 [ 0, %[[FOR_BODY]] ], [ [[INC:%.*]], %[[FOR_BODY1]] ]
 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds [8 x i8], ptr [[TMP1]], i64 [[I_010]]
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I]]) ]
 ; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr [[ADD_PTR_I]], align 8
 ; CHECK-NEXT:    [[ADD:%.*]] = fadd double [[TMP2]], 1.000000e+00
 ; CHECK-NEXT:    store double [[ADD]], ptr [[ADD_PTR_I]], align 8
 ; CHECK-NEXT:    [[INC]] = add nuw i64 [[I_010]], 1
 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i64 [[INC]], [[SUB_PTR_DIV_I_I]]
-; CHECK-NEXT:    br i1 [[CMP_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
+; CHECK-NEXT:    br i1 [[CMP_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY1]]
 ;
 entry:
   %vec.addr = alloca ptr, align 8
@@ -273,7 +275,7 @@ declare void @abort()
 define void @loop_with_signed_induction(ptr noundef nonnull align 8 dereferenceable(24) %vec) {
 ; CHECK-LABEL: define void @loop_with_signed_induction(
 ; CHECK-SAME: ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(24) [[VEC:%.*]]) local_unnamed_addr #[[ATTR0]] {
-; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:  [[ENTRY:.*:]]
 ; CHECK-NEXT:    [[_M_FINISH_I_I:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 8
 ; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[_M_FINISH_I_I]], align 8, !tbaa [[ANYPTR_TBAA0]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[VEC]], align 8, !tbaa [[ANYPTR_TBAA5]]
@@ -283,18 +285,20 @@ define void @loop_with_signed_induction(ptr noundef nonnull align 8 dereferencea
 ; CHECK-NEXT:    [[SUB_PTR_DIV_I_I:%.*]] = ashr exact i64 [[SUB_PTR_SUB_I_I]], 3
 ; CHECK-NEXT:    [[CMP9:%.*]] = icmp sgt i64 [[SUB_PTR_DIV_I_I]], 0
 ; CHECK-NEXT:    br i1 [[CMP9]], label %[[FOR_BODY:.*]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[TMP1]]) ]
+; CHECK-NEXT:    br label %[[FOR_BODY1:.*]]
 ; CHECK:       [[FOR_COND_CLEANUP]]:
 ; CHECK-NEXT:    ret void
-; CHECK:       [[FOR_BODY]]:
-; CHECK-NEXT:    [[I_010:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
+; CHECK:       [[FOR_BODY1]]:
+; CHECK-NEXT:    [[I_010:%.*]] = phi i64 [ 0, %[[FOR_BODY]] ], [ [[INC:%.*]], %[[FOR_BODY1]] ]
 ; CHECK-NEXT:    [[ADD_PTR_I:%.*]] = getelementptr inbounds nuw [8 x i8], ptr [[TMP1]], i64 [[I_010]]
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[ADD_PTR_I]]) ]
 ; CHECK-NEXT:    [[TMP2:%.*]] = load double, ptr [[ADD_PTR_I]], align 8, !tbaa [[DOUBLE_TBAA6:![0-9]+]]
 ; CHECK-NEXT:    [[ADD:%.*]] = fadd double [[TMP2]], 1.000000e+00
 ; CHECK-NEXT:    store double [[ADD]], ptr [[ADD_PTR_I]], align 8, !tbaa [[DOUBLE_TBAA6]]
 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_010]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[INC]], [[SUB_PTR_DIV_I_I]]
-; CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+; CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY1]], label %[[FOR_COND_CLEANUP]]
 ;
 entry:
   %vec.addr = alloca ptr, align 8

>From 4371ddbd394dad77a3f7dffe160be093348906b8 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 15 Jun 2026 10:29:00 +0200
Subject: [PATCH 4/4] Don't run AddReturnAttributes

---
 llvm/lib/Transforms/Utils/InlineFunction.cpp  |   2 -
 llvm/test/Transforms/Inline/nonnull.ll        | 123 ++++--
 .../Inline/ret_attr_align_and_noundef.ll      | 404 ++++++++++++------
 .../test/Transforms/Inline/ret_attr_update.ll |   6 +-
 4 files changed, 364 insertions(+), 171 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index f1d009702fc56..ed354aa9887c6 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1639,8 +1639,6 @@ static AttrBuilder IdentifyValidUBGeneratingAttributes(CallBase &CB) {
 // behavior or cause new UB.
 static AttrBuilder IdentifyValidPoisonGeneratingAttributes(CallBase &CB) {
   AttrBuilder Valid(CB.getContext());
-  if (CB.hasRetAttr(Attribute::NonNull))
-    Valid.addAttribute(Attribute::NonNull);
   if (CB.hasRetAttr(Attribute::Alignment))
     Valid.addAlignmentAttr(CB.getRetAlign());
   if (std::optional<ConstantRange> Range = CB.getRange())
diff --git a/llvm/test/Transforms/Inline/nonnull.ll b/llvm/test/Transforms/Inline/nonnull.ll
index 4c8e16bccc90c..0f6bc03de9776 100644
--- a/llvm/test/Transforms/Inline/nonnull.ll
+++ b/llvm/test/Transforms/Inline/nonnull.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -S -passes=inline %s | FileCheck %s
-; RUN: opt -S -passes='module-inline' %s | FileCheck %s
+; RUN: opt -S -passes=inline %s | FileCheck --check-prefixes=CHECK,INLINE %s
+; RUN: opt -S -passes='module-inline' %s | FileCheck --check-prefixes=CHECK,INLINE-MODULE %s
 
 declare void @foo()
 declare void @bar()
@@ -51,10 +51,15 @@ done:
 
 ; Positive test - arg is known non null
 define void @caller(ptr nonnull %arg) {
-; CHECK-LABEL: define void @caller
-; CHECK-SAME: (ptr nonnull [[ARG:%.*]]) {
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    ret void
+; INLINE-LABEL: define void @caller
+; INLINE-SAME: (ptr nonnull [[ARG:%.*]]) {
+; INLINE-NEXT:    call void @bar()
+; INLINE-NEXT:    ret void
+;
+; INLINE-MODULE-LABEL: define void @caller
+; INLINE-MODULE-SAME: (ptr nonnull [[ARG:%.*]]) {
+; INLINE-MODULE-NEXT:    call void @bar(), !inline_history [[META0:![0-9]+]]
+; INLINE-MODULE-NEXT:    ret void
 ;
   call void @callee(ptr nonnull %arg)
   ret void
@@ -72,27 +77,49 @@ define void @caller2(ptr %arg) {
 }
 
 define void @caller3(ptr %arg) {
-; CHECK-LABEL: define void @caller3
-; CHECK-SAME: (ptr [[ARG:%.*]]) {
-; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq ptr [[ARG]], null
-; CHECK-NEXT:    br i1 [[CMP_I]], label [[EXPENSIVE_I:%.*]], label [[DONE_I:%.*]]
-; CHECK:       expensive.i:
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[CALLEE_EXIT:%.*]]
-; CHECK:       done.i:
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    br label [[CALLEE_EXIT]]
-; CHECK:       callee.exit:
-; CHECK-NEXT:    ret void
+; INLINE-LABEL: define void @caller3
+; INLINE-SAME: (ptr [[ARG:%.*]]) {
+; INLINE-NEXT:    [[CMP_I:%.*]] = icmp eq ptr [[ARG]], null
+; INLINE-NEXT:    br i1 [[CMP_I]], label [[EXPENSIVE_I:%.*]], label [[DONE_I:%.*]]
+; INLINE:       expensive.i:
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    call void @foo()
+; INLINE-NEXT:    br label [[CALLEE_EXIT:%.*]]
+; INLINE:       done.i:
+; INLINE-NEXT:    call void @bar()
+; INLINE-NEXT:    br label [[CALLEE_EXIT]]
+; INLINE:       callee.exit:
+; INLINE-NEXT:    ret void
+;
+; INLINE-MODULE-LABEL: define void @caller3
+; INLINE-MODULE-SAME: (ptr [[ARG:%.*]]) {
+; INLINE-MODULE-NEXT:    [[CMP_I:%.*]] = icmp eq ptr [[ARG]], null
+; INLINE-MODULE-NEXT:    br i1 [[CMP_I]], label [[EXPENSIVE_I:%.*]], label [[DONE_I:%.*]]
+; INLINE-MODULE:       expensive.i:
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    call void @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    br label [[CALLEE_EXIT:%.*]]
+; INLINE-MODULE:       done.i:
+; INLINE-MODULE-NEXT:    call void @bar(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    br label [[CALLEE_EXIT]]
+; INLINE-MODULE:       callee.exit:
+; INLINE-MODULE-NEXT:    ret void
 ;
   call void @callee(ptr nonnull %arg)
   ret void
@@ -139,10 +166,15 @@ define nonnull ptr @callee7() {
 }
 
 define ptr @caller7() {
-; CHECK-LABEL: define ptr @caller7() {
-; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @buz() #[[ATTR1]]
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller7() {
+; INLINE-NEXT:    [[R_I:%.*]] = call ptr @buz() #[[ATTR1]]
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller7() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call ptr @buz() #[[ATTR1]], !inline_history [[META1:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call ptr @callee7()
   ret ptr %r
@@ -158,10 +190,15 @@ define nonnull ptr @callee8() {
 }
 
 define ptr @caller8() {
-; CHECK-LABEL: define ptr @caller8() {
-; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @buz()
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller8() {
+; INLINE-NEXT:    [[R_I:%.*]] = call ptr @buz()
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller8() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call ptr @buz(), !inline_history [[META2:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee8()
   ret ptr %r
@@ -179,11 +216,17 @@ define ptr @callee9() {
 }
 
 define ptr @caller9() {
-; CHECK-LABEL: define ptr @caller9() {
-; CHECK-NEXT:    [[R_I:%.*]] = call ptr @buz()
-; CHECK-NEXT:    call void @foo() #[[ATTR2]]
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller9() {
+; INLINE-NEXT:    [[R_I:%.*]] = call ptr @buz()
+; INLINE-NEXT:    call void @foo() #[[ATTR2]]
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller9() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call ptr @buz(), !inline_history [[META3:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @foo() #[[ATTR2]], !inline_history [[META3]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee9()
   ret ptr %r
diff --git a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll
index 031e907711039..8924033350716 100644
--- a/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll
+++ b/llvm/test/Transforms/Inline/ret_attr_align_and_noundef.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -S -passes=inline %s | FileCheck %s
-; RUN: opt -S -passes='module-inline' %s | FileCheck %s
+; RUN: opt -S -passes=inline %s | FileCheck --check-prefixes=CHECK,INLINE %s
+; RUN: opt -S -passes='module-inline' %s | FileCheck --check-prefixes=CHECK,INLINE-MODULE %s
 
 declare ptr @foo()
 declare void @use.ptr(ptr) willreturn nounwind
@@ -21,54 +21,78 @@ define ptr @callee0123() {
 }
 
 define ptr @caller0() {
-; CHECK-LABEL: define ptr @caller0() {
-; CHECK-NEXT:    [[R_I:%.*]] = call dereferenceable(16) ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller0() {
+; INLINE-NEXT:    [[R_I:%.*]] = call dereferenceable(16) ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller0() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call dereferenceable(16) ptr @foo(), !inline_history [[META0:![0-9]+]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call dereferenceable(16) ptr @callee0123()
   ret ptr %r
 }
 
 define ptr @caller1() {
-; CHECK-LABEL: define ptr @caller1() {
-; CHECK-NEXT:    [[R_I:%.*]] = call align 16 ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller1() {
+; INLINE-NEXT:    [[R_I:%.*]] = call align 16 ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller1() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call align 16 ptr @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call align(16) ptr @callee0123()
   ret ptr %r
 }
 
 define ptr @caller2() {
-; CHECK-LABEL: define ptr @caller2() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller2() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller2() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef ptr @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call noundef ptr @callee0123()
   ret ptr %r
 }
 
 define ptr @caller3() {
-; CHECK-LABEL: define ptr @caller3() {
-; CHECK-NEXT:    [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller3() {
+; INLINE-NEXT:    [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller3() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call dereferenceable_or_null(32) ptr @callee0123()
   ret ptr %r
 }
 
 define ptr @caller_0123_dornull() {
-; CHECK-LABEL: define ptr @caller_0123_dornull() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef align 32 dereferenceable_or_null(16) ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller_0123_dornull() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef align 32 dereferenceable_or_null(16) ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller_0123_dornull() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef align 32 dereferenceable_or_null(16) ptr @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call noundef align(32) dereferenceable_or_null(16) ptr @callee0123()
   ret ptr %r
 }
 
 define ptr @caller_0123_d() {
-; CHECK-LABEL: define ptr @caller_0123_d() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef align 32 dereferenceable(16) ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller_0123_d() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef align 32 dereferenceable(16) ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller_0123_d() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef align 32 dereferenceable(16) ptr @foo(), !inline_history [[META0]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call noundef align(32) dereferenceable(16) ptr @callee0123()
   ret ptr %r
@@ -86,10 +110,15 @@ define ptr @callee4() {
 }
 
 define ptr @caller4_fail() {
-; CHECK-LABEL: define ptr @caller4_fail() {
-; CHECK-NEXT:    [[R_I:%.*]] = call ptr @foo()
-; CHECK-NEXT:    call void @bar()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller4_fail() {
+; INLINE-NEXT:    [[R_I:%.*]] = call ptr @foo()
+; INLINE-NEXT:    call void @bar()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller4_fail() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call ptr @foo(), !inline_history [[META1:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @bar(), !inline_history [[META1]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call noundef align(256) ptr @callee4()
   ret ptr %r
@@ -105,18 +134,26 @@ define ptr @callee5() {
 }
 
 define ptr @caller5_fail() {
-; CHECK-LABEL: define ptr @caller5_fail() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef align 64 ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller5_fail() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef align 64 ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller5_fail() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef align 64 ptr @foo(), !inline_history [[META2:![0-9]+]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call noundef align(32) ptr @callee5()
   ret ptr %r
 }
 
 define ptr @caller5_okay() {
-; CHECK-LABEL: define ptr @caller5_okay() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef align 128 ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller5_okay() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef align 128 ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller5_okay() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef align 128 ptr @foo(), !inline_history [[META2]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call noundef align(128) ptr @callee5()
   ret ptr %r
@@ -132,18 +169,26 @@ define ptr @callee6() {
 }
 
 define ptr @caller6_fail() {
-; CHECK-LABEL: define ptr @caller6_fail() {
-; CHECK-NEXT:    [[R_I:%.*]] = call dereferenceable(16) ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller6_fail() {
+; INLINE-NEXT:    [[R_I:%.*]] = call dereferenceable(16) ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller6_fail() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call dereferenceable(16) ptr @foo(), !inline_history [[META3:![0-9]+]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call dereferenceable(8) ptr @callee6()
   ret ptr %r
 }
 
 define ptr @caller6_okay() {
-; CHECK-LABEL: define ptr @caller6_okay() {
-; CHECK-NEXT:    [[R_I:%.*]] = call dereferenceable(32) ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller6_okay() {
+; INLINE-NEXT:    [[R_I:%.*]] = call dereferenceable(32) ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller6_okay() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call dereferenceable(32) ptr @foo(), !inline_history [[META3]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call dereferenceable(32) ptr @callee6()
   ret ptr %r
@@ -159,18 +204,26 @@ define ptr @callee7() {
 }
 
 define ptr @caller7_fail() {
-; CHECK-LABEL: define ptr @caller7_fail() {
-; CHECK-NEXT:    [[R_I:%.*]] = call dereferenceable_or_null(16) ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller7_fail() {
+; INLINE-NEXT:    [[R_I:%.*]] = call dereferenceable_or_null(16) ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller7_fail() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call dereferenceable_or_null(16) ptr @foo(), !inline_history [[META4:![0-9]+]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call dereferenceable_or_null(8) ptr @callee7()
   ret ptr %r
 }
 
 define ptr @caller7_okay() {
-; CHECK-LABEL: define ptr @caller7_okay() {
-; CHECK-NEXT:    [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo()
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller7_okay() {
+; INLINE-NEXT:    [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo()
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller7_okay() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call dereferenceable_or_null(32) ptr @foo(), !inline_history [[META4]]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call dereferenceable_or_null(32) ptr @callee7()
   ret ptr %r
@@ -186,11 +239,17 @@ define ptr @callee8() {
 }
 
 define ptr @caller8_okay_use_after_poison_anyways() {
-; CHECK-LABEL: define ptr @caller8_okay_use_after_poison_anyways() {
-; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @foo()
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller8_okay_use_after_poison_anyways() {
+; INLINE-NEXT:    [[R_I:%.*]] = call ptr @foo()
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    call void @use.ptr(ptr [[R_I]])
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller8_okay_use_after_poison_anyways() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call ptr @foo(), !inline_history [[META5:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    call void @use.ptr(ptr [[R_I]])
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee8()
   call void @use.ptr(ptr %r)
@@ -207,11 +266,17 @@ define ptr @callee9() {
 }
 
 define ptr @caller9_fail_creates_ub() {
-; CHECK-LABEL: define ptr @caller9_fail_creates_ub() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef ptr @foo()
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller9_fail_creates_ub() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef ptr @foo()
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    call void @use.ptr(ptr [[R_I]])
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller9_fail_creates_ub() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef ptr @foo(), !inline_history [[META6:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    call void @use.ptr(ptr [[R_I]])
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee9()
   call void @use.ptr(ptr %r)
@@ -219,11 +284,17 @@ define ptr @caller9_fail_creates_ub() {
 }
 
 define ptr @caller9_okay_is_ub_anyways() {
-; CHECK-LABEL: define ptr @caller9_okay_is_ub_anyways() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef nonnull ptr @foo()
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller9_okay_is_ub_anyways() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef ptr @foo()
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    call void @use.ptr(ptr [[R_I]])
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller9_okay_is_ub_anyways() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef ptr @foo(), !inline_history [[META6]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    call void @use.ptr(ptr [[R_I]])
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call noundef nonnull ptr @callee9()
   call void @use.ptr(ptr %r)
@@ -242,33 +313,51 @@ define ptr @callee10() {
 }
 
 define ptr @caller10_fail_maybe_poison() {
-; CHECK-LABEL: define ptr @caller10_fail_maybe_poison() {
-; CHECK-NEXT:    [[R_I:%.*]] = call ptr @foo()
-; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller10_fail_maybe_poison() {
+; INLINE-NEXT:    [[R_I:%.*]] = call ptr @foo()
+; INLINE-NEXT:    call void @use.ptr(ptr [[R_I]])
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller10_fail_maybe_poison() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call ptr @foo(), !inline_history [[META7:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @use.ptr(ptr [[R_I]]), !inline_history [[META7]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee10()
   ret ptr %r
 }
 
 define ptr @caller10_okay_will_be_ub() {
-; CHECK-LABEL: define ptr @caller10_okay_will_be_ub() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef nonnull ptr @foo()
-; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller10_okay_will_be_ub() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef ptr @foo()
+; INLINE-NEXT:    call void @use.ptr(ptr [[R_I]])
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller10_okay_will_be_ub() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef ptr @foo(), !inline_history [[META7]]
+; INLINE-MODULE-NEXT:    call void @use.ptr(ptr [[R_I]]), !inline_history [[META7]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call noundef nonnull ptr @callee10()
   ret ptr %r
 }
 
 define noundef ptr @caller10_okay_will_be_ub_todo() {
-; CHECK-LABEL: define noundef ptr @caller10_okay_will_be_ub_todo() {
-; CHECK-NEXT:    [[R_I:%.*]] = call ptr @foo()
-; CHECK-NEXT:    call void @use.ptr(ptr [[R_I]])
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define noundef ptr @caller10_okay_will_be_ub_todo() {
+; INLINE-NEXT:    [[R_I:%.*]] = call ptr @foo()
+; INLINE-NEXT:    call void @use.ptr(ptr [[R_I]])
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define noundef ptr @caller10_okay_will_be_ub_todo() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call ptr @foo(), !inline_history [[META7]]
+; INLINE-MODULE-NEXT:    call void @use.ptr(ptr [[R_I]]), !inline_history [[META7]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee10()
   ret ptr %r
@@ -300,20 +389,35 @@ False:
 }
 
 define ptr @caller11_todo() {
-; CHECK-LABEL: define ptr @caller11_todo() {
-; CHECK-NEXT:    [[R_I:%.*]] = call ptr @foo()
-; CHECK-NEXT:    [[COND_I:%.*]] = call i1 @val() #[[ATTR0]]
-; CHECK-NEXT:    br i1 [[COND_I]], label [[TRUE_I:%.*]], label [[FALSE_I:%.*]]
-; CHECK:       True.i:
-; CHECK-NEXT:    call void @baz() #[[ATTR0]]
-; CHECK-NEXT:    br label [[CALLEE11_EXIT:%.*]]
-; CHECK:       False.i:
-; CHECK-NEXT:    call void @bar() #[[ATTR0]]
-; CHECK-NEXT:    [[COND2_I:%.*]] = call i1 @val()
-; CHECK-NEXT:    br label [[CALLEE11_EXIT]]
-; CHECK:       callee11.exit:
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller11_todo() {
+; INLINE-NEXT:    [[R_I:%.*]] = call ptr @foo()
+; INLINE-NEXT:    [[COND_I:%.*]] = call i1 @val() #[[ATTR0]]
+; INLINE-NEXT:    br i1 [[COND_I]], label [[TRUE_I:%.*]], label [[FALSE_I:%.*]]
+; INLINE:       True.i:
+; INLINE-NEXT:    call void @baz() #[[ATTR0]]
+; INLINE-NEXT:    br label [[CALLEE11_EXIT:%.*]]
+; INLINE:       False.i:
+; INLINE-NEXT:    call void @bar() #[[ATTR0]]
+; INLINE-NEXT:    [[COND2_I:%.*]] = call i1 @val()
+; INLINE-NEXT:    br label [[CALLEE11_EXIT]]
+; INLINE:       callee11.exit:
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller11_todo() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call ptr @foo(), !inline_history [[META8:![0-9]+]]
+; INLINE-MODULE-NEXT:    [[COND_I:%.*]] = call i1 @val() #[[ATTR0]], !inline_history [[META8]]
+; INLINE-MODULE-NEXT:    br i1 [[COND_I]], label [[TRUE_I:%.*]], label [[FALSE_I:%.*]]
+; INLINE-MODULE:       True.i:
+; INLINE-MODULE-NEXT:    call void @baz() #[[ATTR0]], !inline_history [[META8]]
+; INLINE-MODULE-NEXT:    br label [[CALLEE11_EXIT:%.*]]
+; INLINE-MODULE:       False.i:
+; INLINE-MODULE-NEXT:    call void @bar() #[[ATTR0]], !inline_history [[META8]]
+; INLINE-MODULE-NEXT:    [[COND2_I:%.*]] = call i1 @val(), !inline_history [[META8]]
+; INLINE-MODULE-NEXT:    br label [[CALLEE11_EXIT]]
+; INLINE-MODULE:       callee11.exit:
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee11()
   ret ptr %r
@@ -335,13 +439,21 @@ define ptr @callee12() {
 }
 
 define ptr @caller12_todo() {
-; CHECK-LABEL: define ptr @caller12_todo() {
-; CHECK-NEXT:    [[P_I:%.*]] = call ptr @foo()
-; CHECK-NEXT:    [[COND_I:%.*]] = call i1 @val() #[[ATTR0]]
-; CHECK-NEXT:    [[PP_I:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_I]], i64 -4)
-; CHECK-NEXT:    [[R_I:%.*]] = select i1 [[COND_I]], ptr [[P_I]], ptr [[PP_I]]
-; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
-; CHECK-NEXT:    ret ptr [[R_I]]
+; INLINE-LABEL: define ptr @caller12_todo() {
+; INLINE-NEXT:    [[P_I:%.*]] = call ptr @foo()
+; INLINE-NEXT:    [[COND_I:%.*]] = call i1 @val() #[[ATTR0]]
+; INLINE-NEXT:    [[PP_I:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_I]], i64 -4)
+; INLINE-NEXT:    [[R_I:%.*]] = select i1 [[COND_I]], ptr [[P_I]], ptr [[PP_I]]
+; INLINE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-NEXT:    ret ptr [[R_I]]
+;
+; INLINE-MODULE-LABEL: define ptr @caller12_todo() {
+; INLINE-MODULE-NEXT:    [[P_I:%.*]] = call ptr @foo(), !inline_history [[META9:![0-9]+]]
+; INLINE-MODULE-NEXT:    [[COND_I:%.*]] = call i1 @val() #[[ATTR0]], !inline_history [[META9]]
+; INLINE-MODULE-NEXT:    [[PP_I:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_I]], i64 -4)
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = select i1 [[COND_I]], ptr [[P_I]], ptr [[PP_I]]
+; INLINE-MODULE-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
+; INLINE-MODULE-NEXT:    ret ptr [[R_I]]
 ;
   %r = call nonnull ptr @callee12()
   ret ptr %r
@@ -357,10 +469,15 @@ define i8 @callee13() {
 }
 
 define i8 @caller13_okay_use_after_poison_anyways() {
-; CHECK-LABEL: define i8 @caller13_okay_use_after_poison_anyways() {
-; CHECK-NEXT:    [[R_I:%.*]] = call range(i8 0, 10) i8 @val8()
-; CHECK-NEXT:    call void @use.val(i8 [[R_I]])
-; CHECK-NEXT:    ret i8 [[R_I]]
+; INLINE-LABEL: define i8 @caller13_okay_use_after_poison_anyways() {
+; INLINE-NEXT:    [[R_I:%.*]] = call range(i8 0, 10) i8 @val8()
+; INLINE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-NEXT:    ret i8 [[R_I]]
+;
+; INLINE-MODULE-LABEL: define i8 @caller13_okay_use_after_poison_anyways() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call range(i8 0, 10) i8 @val8(), !inline_history [[META10:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-MODULE-NEXT:    ret i8 [[R_I]]
 ;
   %r = call range(i8 0, 10) i8 @callee13()
   call void @use.val(i8 %r)
@@ -377,10 +494,15 @@ define i8 @callee14() {
 }
 
 define i8 @caller14_fail_creates_ub() {
-; CHECK-LABEL: define i8 @caller14_fail_creates_ub() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef i8 @val8()
-; CHECK-NEXT:    call void @use.val(i8 [[R_I]])
-; CHECK-NEXT:    ret i8 [[R_I]]
+; INLINE-LABEL: define i8 @caller14_fail_creates_ub() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef i8 @val8()
+; INLINE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-NEXT:    ret i8 [[R_I]]
+;
+; INLINE-MODULE-LABEL: define i8 @caller14_fail_creates_ub() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef i8 @val8(), !inline_history [[META11:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-MODULE-NEXT:    ret i8 [[R_I]]
 ;
   %r = call range(i8 0, 10) i8 @callee14()
   call void @use.val(i8 %r)
@@ -388,10 +510,15 @@ define i8 @caller14_fail_creates_ub() {
 }
 
 define i8 @caller14_okay_is_ub_anyways() {
-; CHECK-LABEL: define i8 @caller14_okay_is_ub_anyways() {
-; CHECK-NEXT:    [[R_I:%.*]] = call noundef range(i8 0, 10) i8 @val8()
-; CHECK-NEXT:    call void @use.val(i8 [[R_I]])
-; CHECK-NEXT:    ret i8 [[R_I]]
+; INLINE-LABEL: define i8 @caller14_okay_is_ub_anyways() {
+; INLINE-NEXT:    [[R_I:%.*]] = call noundef range(i8 0, 10) i8 @val8()
+; INLINE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-NEXT:    ret i8 [[R_I]]
+;
+; INLINE-MODULE-LABEL: define i8 @caller14_okay_is_ub_anyways() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call noundef range(i8 0, 10) i8 @val8(), !inline_history [[META11]]
+; INLINE-MODULE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-MODULE-NEXT:    ret i8 [[R_I]]
 ;
   %r = call noundef range(i8 0, 10) i8 @callee14()
   call void @use.val(i8 %r)
@@ -408,10 +535,15 @@ define i8 @callee15() {
 }
 
 define i8 @caller15_okay_intersect_ranges() {
-; CHECK-LABEL: define i8 @caller15_okay_intersect_ranges() {
-; CHECK-NEXT:    [[R_I:%.*]] = call range(i8 5, 7) i8 @val8()
-; CHECK-NEXT:    call void @use.val(i8 [[R_I]])
-; CHECK-NEXT:    ret i8 [[R_I]]
+; INLINE-LABEL: define i8 @caller15_okay_intersect_ranges() {
+; INLINE-NEXT:    [[R_I:%.*]] = call range(i8 5, 7) i8 @val8()
+; INLINE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-NEXT:    ret i8 [[R_I]]
+;
+; INLINE-MODULE-LABEL: define i8 @caller15_okay_intersect_ranges() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call range(i8 5, 7) i8 @val8(), !inline_history [[META12:![0-9]+]]
+; INLINE-MODULE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-MODULE-NEXT:    ret i8 [[R_I]]
 ;
   %r = call range(i8 0, 7) i8 @callee15()
   call void @use.val(i8 %r)
@@ -419,10 +551,15 @@ define i8 @caller15_okay_intersect_ranges() {
 }
 
 define i8 @caller16_not_intersecting_ranges() {
-; CHECK-LABEL: define i8 @caller16_not_intersecting_ranges() {
-; CHECK-NEXT:    [[R_I:%.*]] = call range(i8 0, 0) i8 @val8()
-; CHECK-NEXT:    call void @use.val(i8 [[R_I]])
-; CHECK-NEXT:    ret i8 [[R_I]]
+; INLINE-LABEL: define i8 @caller16_not_intersecting_ranges() {
+; INLINE-NEXT:    [[R_I:%.*]] = call range(i8 0, 0) i8 @val8()
+; INLINE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-NEXT:    ret i8 [[R_I]]
+;
+; INLINE-MODULE-LABEL: define i8 @caller16_not_intersecting_ranges() {
+; INLINE-MODULE-NEXT:    [[R_I:%.*]] = call range(i8 0, 0) i8 @val8(), !inline_history [[META12]]
+; INLINE-MODULE-NEXT:    call void @use.val(i8 [[R_I]])
+; INLINE-MODULE-NEXT:    ret i8 [[R_I]]
 ;
   %r = call range(i8 0, 5) i8 @callee15()
   call void @use.val(i8 %r)
@@ -430,8 +567,9 @@ define i8 @caller16_not_intersecting_ranges() {
 }
 
 define i8 @callee_range_multi_ret(i1 %c) {
-; CHECK-LABEL: define i8 @callee_range_multi_ret(i1 %c) {
-; CHECK-NEXT:    br i1 %c, label %bb1, label %bb2
+; CHECK-LABEL: define i8 @callee_range_multi_ret
+; CHECK-SAME: (i1 [[C:%.*]]) {
+; CHECK-NEXT:    br i1 [[C]], label [[BB1:%.*]], label [[BB2:%.*]]
 ; CHECK:       bb1:
 ; CHECK-NEXT:    [[R1:%.*]] = call range(i8 0, 20) i8 @val8()
 ; CHECK-NEXT:    ret i8 [[R1]]
@@ -451,17 +589,31 @@ bb2:
 }
 
 define i8 @caller_range_multi_ret_okay_intersect(i1 %c) {
-; CHECK-LABEL: define i8 @caller_range_multi_ret_okay_intersect(i1 %c) {
-; CHECK-NEXT:    br i1 %c, label %bb1.i, label %bb2.i
-; CHECK:       bb1.i:
-; CHECK-NEXT:    [[R1_I:%.*]] = call range(i8 5, 20) i8 @val8()
-; CHECK-NEXT:    br label %callee_range_multi_ret.exit
-; CHECK:       bb2.i:
-; CHECK-NEXT:    [[R2_I:%.*]] = call range(i8 10, 25) i8 @val8()
-; CHECK-NEXT:    br label %callee_range_multi_ret.exit
-; CHECK:       callee_range_multi_ret.exit:
-; CHECK-NEXT:    [[R_I:%.*]] = phi i8 [ [[R1_I]], %bb1.i ], [ [[R2_I]], %bb2.i ]
-; CHECK-NEXT:    ret i8 [[R_I]]
+; INLINE-LABEL: define i8 @caller_range_multi_ret_okay_intersect
+; INLINE-SAME: (i1 [[C:%.*]]) {
+; INLINE-NEXT:    br i1 [[C]], label [[BB1_I:%.*]], label [[BB2_I:%.*]]
+; INLINE:       bb1.i:
+; INLINE-NEXT:    [[R1_I:%.*]] = call range(i8 5, 20) i8 @val8()
+; INLINE-NEXT:    br label [[CALLEE_RANGE_MULTI_RET_EXIT:%.*]]
+; INLINE:       bb2.i:
+; INLINE-NEXT:    [[R2_I:%.*]] = call range(i8 10, 25) i8 @val8()
+; INLINE-NEXT:    br label [[CALLEE_RANGE_MULTI_RET_EXIT]]
+; INLINE:       callee_range_multi_ret.exit:
+; INLINE-NEXT:    [[R1:%.*]] = phi i8 [ [[R1_I]], [[BB1_I]] ], [ [[R2_I]], [[BB2_I]] ]
+; INLINE-NEXT:    ret i8 [[R1]]
+;
+; INLINE-MODULE-LABEL: define i8 @caller_range_multi_ret_okay_intersect
+; INLINE-MODULE-SAME: (i1 [[C:%.*]]) {
+; INLINE-MODULE-NEXT:    br i1 [[C]], label [[BB1_I:%.*]], label [[BB2_I:%.*]]
+; INLINE-MODULE:       bb1.i:
+; INLINE-MODULE-NEXT:    [[R1_I:%.*]] = call range(i8 5, 20) i8 @val8(), !inline_history [[META13:![0-9]+]]
+; INLINE-MODULE-NEXT:    br label [[CALLEE_RANGE_MULTI_RET_EXIT:%.*]]
+; INLINE-MODULE:       bb2.i:
+; INLINE-MODULE-NEXT:    [[R2_I:%.*]] = call range(i8 10, 25) i8 @val8(), !inline_history [[META13]]
+; INLINE-MODULE-NEXT:    br label [[CALLEE_RANGE_MULTI_RET_EXIT]]
+; INLINE-MODULE:       callee_range_multi_ret.exit:
+; INLINE-MODULE-NEXT:    [[R1:%.*]] = phi i8 [ [[R1_I]], [[BB1_I]] ], [ [[R2_I]], [[BB2_I]] ]
+; INLINE-MODULE-NEXT:    ret i8 [[R1]]
 ;
   %r = call range(i8 5, 25) i8 @callee_range_multi_ret(i1 %c)
   ret i8 %r
diff --git a/llvm/test/Transforms/Inline/ret_attr_update.ll b/llvm/test/Transforms/Inline/ret_attr_update.ll
index 57d8c3b1f5932..fe4eee799ac86 100644
--- a/llvm/test/Transforms/Inline/ret_attr_update.ll
+++ b/llvm/test/Transforms/Inline/ret_attr_update.ll
@@ -16,7 +16,7 @@ define ptr @callee(ptr %p) alwaysinline {
 define ptr @caller(ptr %ptr, i64 %x) {
 ; CHECK-LABEL: @caller(
 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[X:%.*]]
-; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @foo(ptr noalias [[GEP]])
+; CHECK-NEXT:    [[R_I:%.*]] = call ptr @foo(ptr noalias [[GEP]])
 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(ptr [[R_I]]) ]
 ; CHECK-NEXT:    ret ptr [[R_I]]
 ;
@@ -183,10 +183,10 @@ define void @test7(ptr %ptr, i64 %x, i1 %cond) {
 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[X:%.*]]
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[PASS_I:%.*]], label [[FAIL_I:%.*]]
 ; CHECK:       pass.i:
-; CHECK-NEXT:    [[R_I:%.*]] = call nonnull ptr @foo(ptr noalias [[GEP]])
+; CHECK-NEXT:    [[R_I:%.*]] = call ptr @foo(ptr noalias [[GEP]])
 ; CHECK-NEXT:    br label [[CALLEE7_EXIT:%.*]]
 ; CHECK:       fail.i:
-; CHECK-NEXT:    [[S_I:%.*]] = call nonnull ptr @baz(ptr [[GEP]])
+; CHECK-NEXT:    [[S_I:%.*]] = call ptr @baz(ptr [[GEP]])
 ; CHECK-NEXT:    br label [[CALLEE7_EXIT]]
 ; CHECK:       callee7.exit:
 ; CHECK-NEXT:    [[T1:%.*]] = phi ptr [ [[R_I]], [[PASS_I]] ], [ [[S_I]], [[FAIL_I]] ]



More information about the llvm-commits mailing list