[clang] [llvm] [FunctionAttrs][Attributor] Update nofree inference (PR #196266)
Nikita Popov via cfe-commits
cfe-commits at lists.llvm.org
Wed May 27 23:59:12 PDT 2026
https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/196266
>From c3a47da19112088c7af8b9ccfcbe6ad7d229963a Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 7 May 2026 10:42:20 +0200
Subject: [PATCH 1/4] Update FunctionAttrs inference
---
.../CodeGen/sanitize-metadata-nosanitize.c | 14 +++++++-------
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 7 +++++--
llvm/test/Transforms/FunctionAttrs/atomic.ll | 2 +-
.../test/Transforms/FunctionAttrs/nocapture.ll | 6 +++---
llvm/test/Transforms/FunctionAttrs/nosync.ll | 18 +++++++++---------
.../test/Transforms/FunctionAttrs/writeonly.ll | 2 +-
6 files changed, 26 insertions(+), 23 deletions(-)
diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c
index 01183709476f9..019853f51e6dd 100644
--- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c
+++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c
@@ -21,7 +21,7 @@ __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) {
sink = p;
}
-// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none)
+// CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none)
// CHECK-LABEL: define dso_local i32 @normal_function(
// CHECK-SAME: ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META7:![0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -38,7 +38,7 @@ int normal_function(int *x, int *y) {
return *y;
}
-// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none)
+// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none)
// CHECK-LABEL: define dso_local i32 @test_disable_sanitize_instrumentation(
// CHECK-SAME: ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -55,7 +55,7 @@ __attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_ins
return *y;
}
-// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none)
+// CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none)
// CHECK-LABEL: define dso_local i32 @test_no_sanitize_thread(
// CHECK-SAME: ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] !pcsections [[META13:![0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -72,7 +72,7 @@ __attribute__((no_sanitize("thread"))) int test_no_sanitize_thread(int *x, int *
return *y;
}
-// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none)
+// CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none)
// CHECK-LABEL: define dso_local i32 @test_no_sanitize_all(
// CHECK-SAME: ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR3]] !pcsections [[META13]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -90,9 +90,9 @@ __attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) {
}
//.
// CHECK: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
-// CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
-// CHECK: attributes #[[ATTR2]] = { disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
-// CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR1]] = { mustprogress norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR2]] = { disable_sanitizer_instrumentation mustprogress norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR3]] = { mustprogress norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
// CHECK: attributes #[[ATTR4:[0-9]+]] = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
//.
// CHECK: [[META0:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 1aea1ee301ad5..afc48747a6bcd 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -1919,8 +1919,11 @@ static bool InstrBreaksNonThrowing(Instruction &I, const SCCNodeSet &SCCNodes) {
/// Helper for NoFree inference predicate InstrBreaksAttribute.
static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes) {
CallBase *CB = dyn_cast<CallBase>(&I);
- if (!CB)
- return false;
+ if (!CB) {
+ // Synchronization may establish happens-before with a free on another
+ // thread.
+ return I.maySynchronize();
+ }
if (CB->hasFnAttr(Attribute::NoFree))
return false;
diff --git a/llvm/test/Transforms/FunctionAttrs/atomic.ll b/llvm/test/Transforms/FunctionAttrs/atomic.ll
index 8635f2bbdc498..bd99ba2f0b18e 100644
--- a/llvm/test/Transforms/FunctionAttrs/atomic.ll
+++ b/llvm/test/Transforms/FunctionAttrs/atomic.ll
@@ -21,7 +21,7 @@ entry:
; A function with an Acquire load is not readonly.
define i32 @test2(ptr %x) uwtable ssp {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind ssp willreturn memory(argmem: readwrite) uwtable
+; CHECK: Function Attrs: mustprogress norecurse nounwind ssp willreturn memory(argmem: readwrite) uwtable
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = load atomic i32, ptr [[X:%.*]] seq_cst, align 4
diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
index e28891b7f1229..53b3be2218db3 100644
--- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -646,7 +646,7 @@ define void @test6_2(ptr %x6_2, ptr %y6_2, ptr %z6_2) {
}
define void @test_cmpxchg(ptr %p) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; FNATTRS: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; FNATTRS-LABEL: define void @test_cmpxchg
; FNATTRS-SAME: (ptr captures(none) [[P:%.*]]) #[[ATTR13:[0-9]+]] {
; FNATTRS-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], i32 0, i32 1 acquire monotonic, align 4
@@ -663,7 +663,7 @@ define void @test_cmpxchg(ptr %p) {
}
define void @test_cmpxchg_ptr(ptr %p, ptr %q) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; FNATTRS: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; FNATTRS-LABEL: define void @test_cmpxchg_ptr
; FNATTRS-SAME: (ptr captures(none) [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR13]] {
; FNATTRS-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], ptr null, ptr [[Q]] acquire monotonic, align 8
@@ -680,7 +680,7 @@ define void @test_cmpxchg_ptr(ptr %p, ptr %q) {
}
define void @test_atomicrmw(ptr %p) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; FNATTRS: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; FNATTRS-LABEL: define void @test_atomicrmw
; FNATTRS-SAME: (ptr captures(none) [[P:%.*]]) #[[ATTR13]] {
; FNATTRS-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i32 1 seq_cst, align 4
diff --git a/llvm/test/Transforms/FunctionAttrs/nosync.ll b/llvm/test/Transforms/FunctionAttrs/nosync.ll
index db2aaa06aad1f..c00eac2fc04b1 100644
--- a/llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nosync.ll
@@ -48,7 +48,7 @@ define i32 @test4(i32 %a, i32 %b) {
; negative case - explicit sync
define void @test5(ptr %p) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CHECK-LABEL: @test5(
; CHECK-NEXT: store atomic i8 0, ptr [[P:%.*]] seq_cst, align 1
; CHECK-NEXT: ret void
@@ -59,7 +59,7 @@ define void @test5(ptr %p) {
; negative case - explicit sync
define i8 @test6(ptr %p) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CHECK-LABEL: @test6(
; CHECK-NEXT: [[V:%.*]] = load atomic i8, ptr [[P:%.*]] seq_cst, align 1
; CHECK-NEXT: ret i8 [[V]]
@@ -70,7 +70,7 @@ define i8 @test6(ptr %p) {
; negative case - explicit sync
define void @test7(ptr %p) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CHECK-LABEL: @test7(
; CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P:%.*]], i8 0 seq_cst, align 1
; CHECK-NEXT: ret void
@@ -81,7 +81,7 @@ define void @test7(ptr %p) {
; negative case - explicit sync
define void @test8(ptr %p) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn
; CHECK-LABEL: @test8(
; CHECK-NEXT: fence seq_cst
; CHECK-NEXT: ret void
@@ -103,7 +103,7 @@ define void @test9(ptr %p) {
; atomic load with monotonic ordering
define i32 @load_monotonic(ptr nocapture readonly %0) norecurse nounwind uwtable {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) uwtable
; CHECK-LABEL: @load_monotonic(
; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, ptr [[TMP0:%.*]] monotonic, align 4
; CHECK-NEXT: ret i32 [[TMP2]]
@@ -114,7 +114,7 @@ define i32 @load_monotonic(ptr nocapture readonly %0) norecurse nounwind uwtable
; atomic store with monotonic ordering.
define void @store_monotonic(ptr nocapture %0) norecurse nounwind uwtable {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) uwtable
; CHECK-LABEL: @store_monotonic(
; CHECK-NEXT: store atomic i32 10, ptr [[TMP0:%.*]] monotonic, align 4
; CHECK-NEXT: ret void
@@ -126,7 +126,7 @@ define void @store_monotonic(ptr nocapture %0) norecurse nounwind uwtable {
; negative, should not deduce nosync
; atomic load with acquire ordering.
define i32 @load_acquire(ptr nocapture readonly %0) norecurse nounwind uwtable {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) uwtable
; CHECK-LABEL: @load_acquire(
; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, ptr [[TMP0:%.*]] acquire, align 4
; CHECK-NEXT: ret i32 [[TMP2]]
@@ -160,7 +160,7 @@ define void @store_unordered(ptr nocapture %0) norecurse nounwind uwtable {
; negative, should not deduce nosync
; atomic load with release ordering
define void @load_release(ptr nocapture %0) norecurse nounwind uwtable {
-; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable
+; CHECK: Function Attrs: norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable
; CHECK-LABEL: @load_release(
; CHECK-NEXT: store atomic volatile i32 10, ptr [[TMP0:%.*]] release, align 4
; CHECK-NEXT: ret void
@@ -171,7 +171,7 @@ define void @load_release(ptr nocapture %0) norecurse nounwind uwtable {
; negative volatile, relaxed atomic
define void @load_volatile_release(ptr nocapture %0) norecurse nounwind uwtable {
-; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable
+; CHECK: Function Attrs: norecurse nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) uwtable
; CHECK-LABEL: @load_volatile_release(
; CHECK-NEXT: store atomic volatile i32 10, ptr [[TMP0:%.*]] release, align 4
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/FunctionAttrs/writeonly.ll b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
index 75fdb171d94ec..8e8ade356aae3 100644
--- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll
+++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
@@ -162,7 +162,7 @@ define void @test_volatile(ptr %p) {
}
define void @test_atomicrmw(ptr %p) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; FNATTRS: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; FNATTRS-LABEL: define {{[^@]+}}@test_atomicrmw
; FNATTRS-SAME: (ptr captures(none) [[P:%.*]]) #[[ATTR7:[0-9]+]] {
; FNATTRS-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1
>From b30ae3e5d8441d7cd0238f9988f85b22523f8c20 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 7 May 2026 11:04:38 +0200
Subject: [PATCH 2/4] Update Attributor inference
---
.../Transforms/IPO/AttributorAttributes.cpp | 46 ++++--
.../ArgumentPromotion/X86/thiscall.ll | 4 +-
.../Transforms/Attributor/align-atomic.ll | 4 +-
llvm/test/Transforms/Attributor/align.ll | 28 ++--
.../Attributor/dereferenceable-1.ll | 4 +-
llvm/test/Transforms/Attributor/liveness.ll | 135 ++++++++----------
llvm/test/Transforms/Attributor/misc.ll | 4 +-
llvm/test/Transforms/Attributor/noalias.ll | 14 +-
.../test/Transforms/Attributor/nocapture-1.ll | 28 ++--
.../test/Transforms/Attributor/nocapture-2.ll | 4 +-
llvm/test/Transforms/Attributor/nofpclass.ll | 131 +++++++++++------
llvm/test/Transforms/Attributor/nofree.ll | 52 ++++---
llvm/test/Transforms/Attributor/nonnull.ll | 30 ++--
llvm/test/Transforms/Attributor/nosync.ll | 30 ++--
llvm/test/Transforms/Attributor/range.ll | 112 ++++++++-------
llvm/test/Transforms/Attributor/readattrs.ll | 10 +-
.../Attributor/undefined_behavior.ll | 44 +++---
.../Attributor/value-simplify-assume.ll | 106 +++++++-------
.../Attributor/value-simplify-instances.ll | 50 ++++---
.../value-simplify-pointer-info-struct.ll | 4 +-
.../Attributor/value-simplify-pointer-info.ll | 109 +++++++-------
.../Transforms/Attributor/value-simplify.ll | 29 ++--
.../Transforms/FunctionAttrs/nocapture.ll | 8 +-
llvm/test/Transforms/FunctionAttrs/nonnull.ll | 18 +--
.../Transforms/FunctionAttrs/readattrs.ll | 24 ++--
.../Transforms/FunctionAttrs/writeonly.ll | 2 +-
.../Transforms/OpenMP/parallel_deletion.ll | 10 +-
27 files changed, 552 insertions(+), 488 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 69b479fb41ea4..2f3cfe2fcc054 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -2281,6 +2281,15 @@ struct AANoFreeImpl : public AANoFree {
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
+ // Make sure that synchronization cannot establish happens-before with a
+ // free on another thread.
+ const IRPosition &IRP = getIRPosition();
+ bool IsKnown;
+ if (!AA::hasAssumedIRAttr<Attribute::NoSync>(
+ A, this, IRPosition::function_scope(IRP), DepClassTy::REQUIRED,
+ IsKnown))
+ return indicatePessimisticFixpoint();
+
auto CheckForNoFree = [&](Instruction &I) {
bool IsKnown;
return AA::hasAssumedIRAttr<Attribute::NoFree>(
@@ -2292,6 +2301,7 @@ struct AANoFreeImpl : public AANoFree {
if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
UsedAssumedInformation))
return indicatePessimisticFixpoint();
+
return ChangeStatus::UNCHANGED;
}
@@ -2346,27 +2356,41 @@ struct AANoFreeFloating : AANoFreeImpl {
return true;
unsigned ArgNo = CB->getArgOperandNo(&U);
+ // Even if the argument is nofree, we still need to check for nocapture,
+ // as the call may capture the argument without freeing it, and the
+ // captured argument is freed later.
bool IsKnown;
- return AA::hasAssumedIRAttr<Attribute::NoFree>(
- A, this, IRPosition::callsite_argument(*CB, ArgNo),
- DepClassTy::REQUIRED, IsKnown);
+ if (!AA::hasAssumedIRAttr<Attribute::NoFree>(
+ A, this, IRPosition::callsite_argument(*CB, ArgNo),
+ DepClassTy::REQUIRED, IsKnown))
+ return false;
+
+ const AANoCapture *NoCaptureAA = nullptr;
+ if (!AA::hasAssumedIRAttr<Attribute::Captures>(
+ A, this, IRPosition::callsite_argument(*CB, ArgNo),
+ DepClassTy::REQUIRED, IsKnown, false, &NoCaptureAA)) {
+ if (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
+ Follow = true;
+ return true;
+ }
+ return false;
+ }
+
+ return true;
}
- if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
- isa<SelectInst>(UserI)) {
+ UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
+ if (!capturesAnyProvenance(CI))
+ return true;
+ if (capturesAnyProvenance(CI.ResultCC)) {
Follow = true;
return true;
}
- if (isa<LoadInst>(UserI))
- return true;
-
- if (isa<StoreInst>(UserI))
- return U.getOperandNo() == StoreInst::getPointerOperandIndex();
if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
return true;
- // Unknown user.
+ // Capturing user.
return false;
};
if (!A.checkForAllUses(Pred, *this, AssociatedValue))
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
index 4795b424b0d2d..139f42c6d36e1 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
@@ -59,8 +59,8 @@ declare ptr @llvm.stacksave()
declare void @llvm.stackrestore(ptr)
;.
; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn }
-; TUNIT: attributes #[[ATTR1]] = { nofree willreturn }
+; TUNIT: attributes #[[ATTR1]] = { willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn }
-; CGSCC: attributes #[[ATTR1]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR1]] = { willreturn }
;.
diff --git a/llvm/test/Transforms/Attributor/align-atomic.ll b/llvm/test/Transforms/Attributor/align-atomic.ll
index 0b363741cc168..3c3db2ce27ca4 100644
--- a/llvm/test/Transforms/Attributor/align-atomic.ll
+++ b/llvm/test/Transforms/Attributor/align-atomic.ll
@@ -26,7 +26,7 @@ define i32 @atomicrmw_add_propagate(ptr align 8 %ptr, i32 %val) {
; Should increase alignment to 8, not 16.
define ptr @atomicrmw_non_ptr_op_no_propagate(ptr %ptr, ptr align 16 %val) {
; CHECK-LABEL: define ptr @atomicrmw_non_ptr_op_no_propagate(
-; CHECK-SAME: ptr nofree noundef nonnull align 2 captures(none) dereferenceable(8) [[PTR:%.*]], ptr nofree align 16 [[VAL:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: ptr nofree noundef nonnull align 2 captures(none) dereferenceable(8) [[PTR:%.*]], ptr align 16 [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[RESULT:%.*]] = atomicrmw xchg ptr [[PTR]], ptr [[VAL]] seq_cst, align 2
; CHECK-NEXT: ret ptr [[RESULT]]
;
@@ -49,7 +49,7 @@ define i32 @cmpxchg_propagate(ptr align 8 %ptr, i32 %cmp, i32 %val) {
; Should not increase alignment
define ptr @cmpxchg_no_propagate(ptr %ptr, ptr align 16 %cmp, ptr align 32 %val) {
; CHECK-LABEL: define ptr @cmpxchg_no_propagate(
-; CHECK-SAME: ptr nofree noundef nonnull align 2 captures(none) dereferenceable(8) [[PTR:%.*]], ptr nofree align 16 [[CMP:%.*]], ptr nofree align 32 [[VAL:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: ptr nofree noundef nonnull align 2 captures(none) dereferenceable(8) [[PTR:%.*]], ptr align 16 [[CMP:%.*]], ptr align 32 [[VAL:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[PAIR:%.*]] = cmpxchg ptr [[PTR]], ptr [[CMP]], ptr [[VAL]] seq_cst monotonic, align 2
; CHECK-NEXT: [[RESULT:%.*]] = extractvalue { ptr, i1 } [[PAIR]], 0
; CHECK-NEXT: ret ptr [[RESULT]]
diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll
index 586aecb7cae1f..904233408c144 100644
--- a/llvm/test/Transforms/Attributor/align.ll
+++ b/llvm/test/Transforms/Attributor/align.ll
@@ -1115,7 +1115,7 @@ entry:
}
define i64 @infer_align_atomicrmw(ptr align 4 %p) {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@infer_align_atomicrmw
; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]]) #[[ATTR12:[0-9]+]] {
; TUNIT-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
@@ -1123,7 +1123,7 @@ define i64 @infer_align_atomicrmw(ptr align 4 %p) {
; TUNIT-NEXT: [[RET:%.*]] = atomicrmw add ptr [[ARRAYIDX1]], i64 4 seq_cst, align 16
; TUNIT-NEXT: ret i64 [[RET]]
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@infer_align_atomicrmw
; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]]) #[[ATTR14:[0-9]+]] {
; CGSCC-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
@@ -1138,17 +1138,17 @@ define i64 @infer_align_atomicrmw(ptr align 4 %p) {
}
define ptr @infer_align_atomicrmw_ptr(ptr align 4 %p, ptr %val) {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@infer_align_atomicrmw_ptr
-; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr nofree [[VAL:%.*]]) #[[ATTR12]] {
+; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr [[VAL:%.*]]) #[[ATTR12]] {
; TUNIT-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
; TUNIT-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3
; TUNIT-NEXT: [[RET:%.*]] = atomicrmw xchg ptr [[ARRAYIDX1]], ptr [[VAL]] seq_cst, align 16
; TUNIT-NEXT: ret ptr [[RET]]
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@infer_align_atomicrmw_ptr
-; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr nofree [[VAL:%.*]]) #[[ATTR14]] {
+; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr [[VAL:%.*]]) #[[ATTR14]] {
; CGSCC-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
; CGSCC-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3
; CGSCC-NEXT: [[RET:%.*]] = atomicrmw xchg ptr [[ARRAYIDX1]], ptr [[VAL]] seq_cst, align 16
@@ -1161,7 +1161,7 @@ define ptr @infer_align_atomicrmw_ptr(ptr align 4 %p, ptr %val) {
}
define i64 @infer_align_cmpxchg(ptr align 4 %p) {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@infer_align_cmpxchg
; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]]) #[[ATTR12]] {
; TUNIT-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
@@ -1170,7 +1170,7 @@ define i64 @infer_align_cmpxchg(ptr align 4 %p) {
; TUNIT-NEXT: [[RET:%.*]] = extractvalue { i64, i1 } [[CMPX]], 0
; TUNIT-NEXT: ret i64 [[RET]]
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@infer_align_cmpxchg
; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]]) #[[ATTR14]] {
; CGSCC-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
@@ -1187,18 +1187,18 @@ define i64 @infer_align_cmpxchg(ptr align 4 %p) {
}
define ptr @infer_align_cmpxchg_ptr(ptr align 4 %p, ptr %cmp0, ptr %cmp1) {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@infer_align_cmpxchg_ptr
-; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr nofree [[CMP0:%.*]], ptr nofree [[CMP1:%.*]]) #[[ATTR12]] {
+; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr [[CMP0:%.*]], ptr [[CMP1:%.*]]) #[[ATTR12]] {
; TUNIT-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
; TUNIT-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3
; TUNIT-NEXT: [[CMPX:%.*]] = cmpxchg ptr [[ARRAYIDX1]], ptr [[CMP0]], ptr [[CMP1]] seq_cst seq_cst, align 16
; TUNIT-NEXT: [[RET:%.*]] = extractvalue { ptr, i1 } [[CMPX]], 0
; TUNIT-NEXT: ret ptr [[RET]]
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@infer_align_cmpxchg_ptr
-; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr nofree [[CMP0:%.*]], ptr nofree [[CMP1:%.*]]) #[[ATTR14]] {
+; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr [[CMP0:%.*]], ptr [[CMP1:%.*]]) #[[ATTR14]] {
; CGSCC-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1
; CGSCC-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3
; CGSCC-NEXT: [[CMPX:%.*]] = cmpxchg ptr [[ARRAYIDX1]], ptr [[CMP0]], ptr [[CMP1]] seq_cst seq_cst, align 16
@@ -1230,7 +1230,7 @@ attributes #2 = { null_pointer_is_valid }
; TUNIT: attributes #[[ATTR9]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read) }
-; TUNIT: attributes #[[ATTR12]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) }
+; TUNIT: attributes #[[ATTR12]] = { mustprogress norecurse nounwind willreturn memory(argmem: readwrite) }
; TUNIT: attributes #[[ATTR13]] = { nofree nosync nounwind }
; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn memory(read) }
; TUNIT: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind willreturn }
@@ -1249,7 +1249,7 @@ attributes #2 = { null_pointer_is_valid }
; CGSCC: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR12]] = { mustprogress nofree nosync nounwind willreturn memory(read) }
; CGSCC: attributes #[[ATTR13]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
-; CGSCC: attributes #[[ATTR14]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) }
+; CGSCC: attributes #[[ATTR14]] = { mustprogress norecurse nounwind willreturn memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR15]] = { nofree nosync willreturn }
; CGSCC: attributes #[[ATTR16]] = { nofree nosync nounwind }
; CGSCC: attributes #[[ATTR17]] = { nofree willreturn memory(read) }
diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
index 5699284128388..33e621c953d13 100644
--- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll
+++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
@@ -820,7 +820,7 @@ f:
; TUNIT: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn memory(write) }
; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind memory(write) }
-; TUNIT: attributes #[[ATTR9]] = { nofree willreturn memory(write) }
+; TUNIT: attributes #[[ATTR9]] = { willreturn memory(write) }
; TUNIT: attributes #[[ATTR10]] = { nounwind }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
@@ -832,7 +832,7 @@ f:
; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
; CGSCC: attributes #[[ATTR7]] = { nofree nounwind willreturn memory(write) }
; CGSCC: attributes #[[ATTR8]] = { nofree nosync nounwind memory(write) }
-; CGSCC: attributes #[[ATTR9]] = { nofree willreturn memory(write) }
+; CGSCC: attributes #[[ATTR9]] = { willreturn memory(write) }
; CGSCC: attributes #[[ATTR10]] = { nounwind }
;.
; TUNIT: [[RNG0]] = !{i64 10, i64 100}
diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll
index 3898c223746b8..e2f3edff940e1 100644
--- a/llvm/test/Transforms/Attributor/liveness.ll
+++ b/llvm/test/Transforms/Attributor/liveness.ll
@@ -154,7 +154,7 @@ cond.end: ; preds = %cond.false, %cond.t
define i32 @dead_block_present(i32 %a, ptr %ptr1) #0 {
; TUNIT: Function Attrs: nosync
; TUNIT-LABEL: define {{[^@]+}}@dead_block_present
-; TUNIT-SAME: (i32 [[A:%.*]], ptr nofree [[PTR1:%.*]]) #[[ATTR7:[0-9]+]] {
+; TUNIT-SAME: (i32 [[A:%.*]], ptr [[PTR1:%.*]]) #[[ATTR7:[0-9]+]] {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
; TUNIT-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
@@ -170,7 +170,7 @@ define i32 @dead_block_present(i32 %a, ptr %ptr1) #0 {
;
; CGSCC: Function Attrs: nosync
; CGSCC-LABEL: define {{[^@]+}}@dead_block_present
-; CGSCC-SAME: (i32 [[A:%.*]], ptr nofree [[PTR1:%.*]]) #[[ATTR9:[0-9]+]] {
+; CGSCC-SAME: (i32 [[A:%.*]], ptr [[PTR1:%.*]]) #[[ATTR9:[0-9]+]] {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
; CGSCC-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
@@ -206,35 +206,20 @@ cond.end: ; preds = %cond.false, %cond.t
; TEST 3: both cond.true and cond.false are dead, therfore cond.end is dead as well.
define i32 @all_dead(i32 %a) #0 {
-; TUNIT: Function Attrs: noreturn
-; TUNIT-LABEL: define {{[^@]+}}@all_dead
-; TUNIT-SAME: (i32 [[A:%.*]]) #[[ATTR4:[0-9]+]] {
-; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
-; TUNIT-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-; TUNIT: cond.true:
-; TUNIT-NEXT: call void @no_return_call() #[[ATTR16]]
-; TUNIT-NEXT: unreachable
-; TUNIT: cond.false:
-; TUNIT-NEXT: call void @no_return_call() #[[ATTR3:[0-9]+]]
-; TUNIT-NEXT: unreachable
-; TUNIT: cond.end:
-; TUNIT-NEXT: unreachable
-;
-; CGSCC: Function Attrs: noreturn
-; CGSCC-LABEL: define {{[^@]+}}@all_dead
-; CGSCC-SAME: (i32 [[A:%.*]]) #[[ATTR4:[0-9]+]] {
-; CGSCC-NEXT: entry:
-; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
-; CGSCC-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-; CGSCC: cond.true:
-; CGSCC-NEXT: call void @no_return_call() #[[ATTR18]]
-; CGSCC-NEXT: unreachable
-; CGSCC: cond.false:
-; CGSCC-NEXT: call void @no_return_call() #[[ATTR3:[0-9]+]]
-; CGSCC-NEXT: unreachable
-; CGSCC: cond.end:
-; CGSCC-NEXT: unreachable
+; CHECK: Function Attrs: noreturn
+; CHECK-LABEL: define {{[^@]+}}@all_dead
+; CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR4:[0-9]+]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
+; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+; CHECK: cond.true:
+; CHECK-NEXT: call void @no_return_call() #[[ATTR3:[0-9]+]]
+; CHECK-NEXT: unreachable
+; CHECK: cond.false:
+; CHECK-NEXT: call void @no_return_call() #[[ATTR3]]
+; CHECK-NEXT: unreachable
+; CHECK: cond.end:
+; CHECK-NEXT: unreachable
;
entry:
%cmp = icmp eq i32 %a, 0
@@ -269,7 +254,7 @@ define i32 @all_live(i32 %a) #0 {
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
; CHECK-NEXT: call void @normal_call()
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn() #[[ATTR4:[0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn() #[[ATTR4]]
; CHECK-NEXT: unreachable
; CHECK: cond.false:
; CHECK-NEXT: call void @normal_call()
@@ -360,7 +345,7 @@ define i32 @invoke_noreturn_nounwind(i32 %a) personality ptr @__gxx_personality_
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
; CHECK-NEXT: call void @normal_call()
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn_nounwind() #[[ATTR3:[0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn_nounwind() #[[ATTR3]]
; CHECK-NEXT: unreachable
; CHECK: cond.false:
; CHECK-NEXT: call void @normal_call()
@@ -932,28 +917,28 @@ define linkonce_odr void @non_exact1() {
define internal void @middle() {
; TUNIT-LABEL: define {{[^@]+}}@middle() {
; TUNIT-NEXT: bb0:
-; TUNIT-NEXT: call void @non_dead_b0() #[[ATTR11:[0-9]+]]
-; TUNIT-NEXT: call void @non_dead_b1() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b2() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b3() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b0() #[[ATTR18:[0-9]+]]
+; TUNIT-NEXT: call void @non_dead_b1() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b2() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b3() #[[ATTR18]]
; TUNIT-NEXT: br label [[BB1:%.*]]
; TUNIT: bb1:
-; TUNIT-NEXT: call void @non_dead_b4() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b5() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b6() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b7() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b4() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b5() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b6() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b7() #[[ATTR18]]
; TUNIT-NEXT: br label [[BB2:%.*]]
; TUNIT: bb2:
-; TUNIT-NEXT: call void @non_dead_b8() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b9() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b10() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b11() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b8() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b9() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b10() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b11() #[[ATTR18]]
; TUNIT-NEXT: br label [[BB3:%.*]]
; TUNIT: bb3:
-; TUNIT-NEXT: call void @non_dead_b12() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b13() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b14() #[[ATTR11]]
-; TUNIT-NEXT: call void @non_dead_b15() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b12() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b13() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b14() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b15() #[[ATTR18]]
; TUNIT-NEXT: br label [[BB4:%.*]]
; TUNIT: bb4:
; TUNIT-NEXT: call void @non_exact2()
@@ -961,28 +946,28 @@ define internal void @middle() {
;
; CGSCC-LABEL: define {{[^@]+}}@middle() {
; CGSCC-NEXT: bb0:
-; CGSCC-NEXT: call void @non_dead_b0() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b1() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b2() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b3() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b0() #[[ATTR20:[0-9]+]]
+; CGSCC-NEXT: call void @non_dead_b1() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b2() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b3() #[[ATTR20]]
; CGSCC-NEXT: br label [[BB1:%.*]]
; CGSCC: bb1:
-; CGSCC-NEXT: call void @non_dead_b4() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b5() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b6() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b7() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b4() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b5() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b6() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b7() #[[ATTR20]]
; CGSCC-NEXT: br label [[BB2:%.*]]
; CGSCC: bb2:
-; CGSCC-NEXT: call void @non_dead_b8() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b9() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b10() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b11() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b8() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b9() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b10() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b11() #[[ATTR20]]
; CGSCC-NEXT: br label [[BB3:%.*]]
; CGSCC: bb3:
-; CGSCC-NEXT: call void @non_dead_b12() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b13() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b14() #[[ATTR19]]
-; CGSCC-NEXT: call void @non_dead_b15() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b12() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b13() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b14() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b15() #[[ATTR20]]
; CGSCC-NEXT: br label [[BB4:%.*]]
; CGSCC: bb4:
; CGSCC-NEXT: call void @non_exact2()
@@ -2199,7 +2184,7 @@ define internal void @useless_arg_almost_sink(ptr %a) {
; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(readwrite, argmem: none)
; TUNIT-LABEL: define {{[^@]+}}@useless_arg_almost_sink
; TUNIT-SAME: () #[[ATTR13]] {
-; TUNIT-NEXT: call void @useless_arg_sink() #[[ATTR11]]
+; TUNIT-NEXT: call void @useless_arg_sink() #[[ATTR11:[0-9]+]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(readwrite, argmem: none)
@@ -2341,7 +2326,7 @@ define i32 @switch_default_dead_caller() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@switch_default_dead_caller
; CGSCC-SAME: () #[[ATTR12]] {
-; CGSCC-NEXT: [[CALL2:%.*]] = tail call noundef i32 @switch_default_dead() #[[ATTR20:[0-9]+]]
+; CGSCC-NEXT: [[CALL2:%.*]] = tail call noundef i32 @switch_default_dead() #[[ATTR21:[0-9]+]]
; CGSCC-NEXT: ret i32 [[CALL2]]
;
%call2 = tail call i32 @switch_default_dead(i64 0)
@@ -2591,7 +2576,7 @@ define void @bad_gep() {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[N1:%.*]] = alloca i8, i32 0, align 1
; TUNIT-NEXT: [[M2:%.*]] = alloca i8, i32 0, align 1
-; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR18:[0-9]+]]
+; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR19:[0-9]+]]
; TUNIT-NEXT: br label [[EXIT:%.*]]
; TUNIT: while.body:
; TUNIT-NEXT: unreachable
@@ -2600,7 +2585,7 @@ define void @bad_gep() {
; TUNIT: if.end:
; TUNIT-NEXT: unreachable
; TUNIT: exit:
-; TUNIT-NEXT: call void @llvm.lifetime.end.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR18]]
+; TUNIT-NEXT: call void @llvm.lifetime.end.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR19]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
@@ -2609,7 +2594,7 @@ define void @bad_gep() {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[N1:%.*]] = alloca i8, i32 0, align 1
; CGSCC-NEXT: [[M2:%.*]] = alloca i8, i32 0, align 1
-; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR21:[0-9]+]]
+; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR22:[0-9]+]]
; CGSCC-NEXT: br label [[EXIT:%.*]]
; CGSCC: while.body:
; CGSCC-NEXT: unreachable
@@ -2618,7 +2603,7 @@ define void @bad_gep() {
; CGSCC: if.end:
; CGSCC-NEXT: unreachable
; CGSCC: exit:
-; CGSCC-NEXT: call void @llvm.lifetime.end.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR21]]
+; CGSCC-NEXT: call void @llvm.lifetime.end.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR22]]
; CGSCC-NEXT: ret void
;
entry:
@@ -2702,7 +2687,8 @@ declare void @llvm.lifetime.end.p0(ptr %1)
; TUNIT: attributes #[[ATTR15:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
; TUNIT: attributes #[[ATTR16]] = { nofree noreturn nounwind }
; TUNIT: attributes #[[ATTR17]] = { nofree nounwind willreturn }
-; TUNIT: attributes #[[ATTR18]] = { nofree willreturn }
+; TUNIT: attributes #[[ATTR18]] = { nosync nounwind willreturn }
+; TUNIT: attributes #[[ATTR19]] = { nofree willreturn }
;.
; CGSCC: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { memory(none) }
@@ -2724,6 +2710,7 @@ declare void @llvm.lifetime.end.p0(ptr %1)
; CGSCC: attributes #[[ATTR17:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR18]] = { nofree noreturn nounwind }
; CGSCC: attributes #[[ATTR19]] = { nofree nounwind willreturn }
-; CGSCC: attributes #[[ATTR20]] = { nofree nosync willreturn }
-; CGSCC: attributes #[[ATTR21]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR20]] = { nounwind willreturn }
+; CGSCC: attributes #[[ATTR21]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR22]] = { nofree willreturn }
;.
diff --git a/llvm/test/Transforms/Attributor/misc.ll b/llvm/test/Transforms/Attributor/misc.ll
index c3458894fe84e..20ac0d65b47b8 100644
--- a/llvm/test/Transforms/Attributor/misc.ll
+++ b/llvm/test/Transforms/Attributor/misc.ll
@@ -101,8 +101,8 @@ declare void @callback1(ptr)
declare void @callback2(ptr)
;.
; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
-; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(write) }
+; TUNIT: attributes #[[ATTR1]] = { nosync nounwind willreturn memory(write) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
-; CGSCC: attributes #[[ATTR1]] = { nofree nounwind willreturn memory(write) }
+; CGSCC: attributes #[[ATTR1]] = { nounwind willreturn memory(write) }
;.
diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll
index b7c295ae4179c..b989daafaedba 100644
--- a/llvm/test/Transforms/Attributor/noalias.ll
+++ b/llvm/test/Transforms/Attributor/noalias.ll
@@ -264,7 +264,7 @@ return:
define ptr @test8(ptr %0) nounwind uwtable {
; CHECK: Function Attrs: nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@test8
-; CHECK-SAME: (ptr [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-SAME: (ptr nofree [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: [[TMP2:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne ptr [[TMP0]], null
; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
@@ -550,13 +550,13 @@ define internal i32 @ret(ptr %arg) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
; TUNIT-LABEL: define {{[^@]+}}@ret
; TUNIT-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR6:[0-9]+]] {
-; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[ARG]], align 4
+; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[ARG]], align 4, !invariant.load [[META0:![0-9]+]]
; TUNIT-NEXT: ret i32 [[L]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
; CGSCC-LABEL: define {{[^@]+}}@ret
; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR7:[0-9]+]] {
-; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[ARG]], align 4
+; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[ARG]], align 4, !invariant.load [[META0:![0-9]+]]
; CGSCC-NEXT: ret i32 [[L]]
;
%l = load i32, ptr %arg
@@ -950,7 +950,7 @@ l2:
; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn memory(read) }
-; TUNIT: attributes #[[ATTR13]] = { nofree willreturn memory(readwrite) }
+; TUNIT: attributes #[[ATTR13]] = { willreturn memory(readwrite) }
; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn memory(write) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
@@ -967,6 +967,10 @@ l2:
; CGSCC: attributes #[[ATTR11]] = { mustprogress nofree nosync nounwind willreturn memory(write) }
; CGSCC: attributes #[[ATTR12]] = { nofree nosync willreturn }
; CGSCC: attributes #[[ATTR13]] = { nofree willreturn memory(read) }
-; CGSCC: attributes #[[ATTR14]] = { nofree willreturn memory(readwrite) }
+; CGSCC: attributes #[[ATTR14]] = { willreturn memory(readwrite) }
; CGSCC: attributes #[[ATTR15]] = { nofree nounwind willreturn memory(write) }
;.
+; TUNIT: [[META0]] = !{}
+;.
+; CGSCC: [[META0]] = !{}
+;.
diff --git a/llvm/test/Transforms/Attributor/nocapture-1.ll b/llvm/test/Transforms/Attributor/nocapture-1.ll
index 285b0ed606724..45a196a7e1eec 100644
--- a/llvm/test/Transforms/Attributor/nocapture-1.ll
+++ b/llvm/test/Transforms/Attributor/nocapture-1.ll
@@ -323,13 +323,13 @@ declare void @external(ptr readonly) nounwind argmemonly
define void @nc4(ptr %p) {
; TUNIT: Function Attrs: nounwind memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@nc4
-; TUNIT-SAME: (ptr nofree [[P:%.*]]) #[[ATTR6:[0-9]+]] {
+; TUNIT-SAME: (ptr [[P:%.*]]) #[[ATTR6:[0-9]+]] {
; TUNIT-NEXT: call void @external(ptr nofree readonly [[P]]) #[[ATTR21:[0-9]+]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nounwind memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@nc4
-; CGSCC-SAME: (ptr nofree [[P:%.*]]) #[[ATTR9:[0-9]+]] {
+; CGSCC-SAME: (ptr [[P:%.*]]) #[[ATTR9:[0-9]+]] {
; CGSCC-NEXT: call void @external(ptr nofree readonly [[P]]) #[[ATTR24:[0-9]+]]
; CGSCC-NEXT: ret void
;
@@ -533,13 +533,13 @@ define void @test6_2(ptr %x6_2, ptr %y6_2, ptr %z6_2) {
}
define void @test_cmpxchg(ptr %p) {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@test_cmpxchg
; TUNIT-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR8:[0-9]+]] {
; TUNIT-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], i32 0, i32 1 acquire monotonic, align 4
; TUNIT-NEXT: ret void
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@test_cmpxchg
; CGSCC-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR11:[0-9]+]] {
; CGSCC-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], i32 0, i32 1 acquire monotonic, align 4
@@ -550,15 +550,15 @@ define void @test_cmpxchg(ptr %p) {
}
define void @test_cmpxchg_ptr(ptr %p, ptr %q) {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@test_cmpxchg_ptr
-; TUNIT-SAME: (ptr nofree noundef nonnull align 8 captures(none) dereferenceable(8) [[P:%.*]], ptr nofree [[Q:%.*]]) #[[ATTR8]] {
+; TUNIT-SAME: (ptr nofree noundef nonnull align 8 captures(none) dereferenceable(8) [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR8]] {
; TUNIT-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], ptr null, ptr [[Q]] acquire monotonic, align 8
; TUNIT-NEXT: ret void
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@test_cmpxchg_ptr
-; CGSCC-SAME: (ptr nofree noundef nonnull align 8 captures(none) dereferenceable(8) [[P:%.*]], ptr nofree [[Q:%.*]]) #[[ATTR11]] {
+; CGSCC-SAME: (ptr nofree noundef nonnull align 8 captures(none) dereferenceable(8) [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR11]] {
; CGSCC-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], ptr null, ptr [[Q]] acquire monotonic, align 8
; CGSCC-NEXT: ret void
;
@@ -567,13 +567,13 @@ define void @test_cmpxchg_ptr(ptr %p, ptr %q) {
}
define void @test_atomicrmw(ptr %p) {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@test_atomicrmw
; TUNIT-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR8]] {
; TUNIT-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i32 1 seq_cst, align 4
; TUNIT-NEXT: ret void
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@test_atomicrmw
; CGSCC-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[P:%.*]]) #[[ATTR11]] {
; CGSCC-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i32 1 seq_cst, align 4
@@ -828,13 +828,13 @@ declare void @val_use(i8 %ptr) readonly nounwind willreturn
define void @ptr_uses(ptr %ptr, ptr %wptr) {
; TUNIT: Function Attrs: mustprogress nosync nounwind willreturn
; TUNIT-LABEL: define {{[^@]+}}@ptr_uses
-; TUNIT-SAME: (ptr nofree [[PTR:%.*]], ptr nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[WPTR:%.*]]) #[[ATTR15:[0-9]+]] {
+; TUNIT-SAME: (ptr [[PTR:%.*]], ptr nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[WPTR:%.*]]) #[[ATTR15:[0-9]+]] {
; TUNIT-NEXT: store i8 0, ptr [[WPTR]], align 1
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: mustprogress nosync nounwind willreturn
; CGSCC-LABEL: define {{[^@]+}}@ptr_uses
-; CGSCC-SAME: (ptr nofree [[PTR:%.*]], ptr nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[WPTR:%.*]]) #[[ATTR18:[0-9]+]] {
+; CGSCC-SAME: (ptr [[PTR:%.*]], ptr nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[WPTR:%.*]]) #[[ATTR18:[0-9]+]] {
; CGSCC-NEXT: store i8 0, ptr [[WPTR]], align 1
; CGSCC-NEXT: ret void
;
@@ -856,7 +856,7 @@ declare ptr @llvm.strip.invariant.group.p0(ptr)
; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR6]] = { nounwind memory(argmem: readwrite) }
; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind memory(write) }
-; TUNIT: attributes #[[ATTR8]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) }
+; TUNIT: attributes #[[ATTR8]] = { mustprogress norecurse nounwind willreturn memory(argmem: readwrite) }
; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind memory(argmem: readwrite) }
; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) }
; TUNIT: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
@@ -884,7 +884,7 @@ declare ptr @llvm.strip.invariant.group.p0(ptr)
; CGSCC: attributes #[[ATTR8]] = { mustprogress nofree nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR9]] = { nounwind memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR10]] = { nofree nosync nounwind memory(write) }
-; CGSCC: attributes #[[ATTR11]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) }
+; CGSCC: attributes #[[ATTR11]] = { mustprogress norecurse nounwind willreturn memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR12]] = { nofree norecurse nosync nounwind memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR13]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) }
; CGSCC: attributes #[[ATTR14]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll b/llvm/test/Transforms/Attributor/nocapture-2.ll
index 6242a1e20a2fe..49669c51ebb1f 100644
--- a/llvm/test/Transforms/Attributor/nocapture-2.ll
+++ b/llvm/test/Transforms/Attributor/nocapture-2.ll
@@ -525,7 +525,7 @@ entry:
define ptr @ret_arg_or_unknown(ptr %b) #0 {
; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define ptr @ret_arg_or_unknown
-; CHECK-SAME: (ptr [[B:%.*]]) #[[ATTR3]] {
+; CHECK-SAME: (ptr nofree [[B:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[B]], null
; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
@@ -550,7 +550,7 @@ ret_unknown:
define ptr @ret_arg_or_unknown_through_phi(ptr %b) #0 {
; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define ptr @ret_arg_or_unknown_through_phi
-; CHECK-SAME: (ptr [[B:%.*]]) #[[ATTR3]] {
+; CHECK-SAME: (ptr nofree [[B:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[B]], null
; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
diff --git a/llvm/test/Transforms/Attributor/nofpclass.ll b/llvm/test/Transforms/Attributor/nofpclass.ll
index 51e25c1ef09be..028a4eed39dc5 100644
--- a/llvm/test/Transforms/Attributor/nofpclass.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass.ll
@@ -275,7 +275,7 @@ define float @mutually_recursive1(float %arg) {
define float @recursive_phi(ptr %ptr) {
; CHECK-LABEL: define nofpclass(nan) float @recursive_phi
-; CHECK-SAME: (ptr nofree [[PTR:%.*]]) {
+; CHECK-SAME: (ptr [[PTR:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[RET:%.*]] = call nofpclass(nan) float @ret_nofpclass_nan()
; CHECK-NEXT: br label [[LOOP:%.*]]
@@ -1878,7 +1878,7 @@ define double @fpext(float noundef nofpclass(inf nan) %arg) {
}
define float @atomicrmw_fadd(ptr %ptr, float nofpclass(inf nan) %val) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CHECK-LABEL: define float @atomicrmw_fadd
; CHECK-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[PTR:%.*]], float nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR6:[0-9]+]] {
; CHECK-NEXT: [[RESULT:%.*]] = atomicrmw fadd ptr [[PTR]], float [[VAL]] seq_cst, align 4
@@ -1904,7 +1904,7 @@ define float @load(ptr %ptr, float noundef nofpclass(nan inf) %val) {
}
define float @load_atomic(ptr %ptr, float noundef nofpclass(nan inf) %val) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; CHECK-LABEL: define noundef nofpclass(ninf nzero nsub nnorm) float @load_atomic
; CHECK-SAME: (ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[PTR:%.*]], float noundef nofpclass(nan inf) [[VAL:%.*]]) #[[ATTR6]] {
; CHECK-NEXT: store atomic float [[VAL]], ptr [[PTR]] seq_cst, align 4
@@ -1934,22 +1934,34 @@ define <8 x float> @shufflevector_shufflevector(<4 x float> nofpclass(inf nan) %
}
define float @constrained_sitofp(i32 %arg) strictfp {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
-; CHECK-LABEL: define nofpclass(nan nzero sub) float @constrained_sitofp
-; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR8:[0-9]+]] {
-; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(nan nzero sub) float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR24]]
-; CHECK-NEXT: ret float [[VAL]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
+; TUNIT-LABEL: define nofpclass(nan nzero sub) float @constrained_sitofp
+; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR8:[0-9]+]] {
+; TUNIT-NEXT: [[VAL:%.*]] = call nofpclass(nan nzero sub) float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR27:[0-9]+]]
+; TUNIT-NEXT: ret float [[VAL]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
+; CGSCC-LABEL: define nofpclass(nan nzero sub) float @constrained_sitofp
+; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR8:[0-9]+]] {
+; CGSCC-NEXT: [[VAL:%.*]] = call nofpclass(nan nzero sub) float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR26:[0-9]+]]
+; CGSCC-NEXT: ret float [[VAL]]
;
%val = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict")
ret float %val
}
define float @constrained_uitofp(i32 %arg) strictfp {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
-; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @constrained_uitofp
-; CHECK-SAME: (i32 [[ARG:%.*]]) #[[ATTR8]] {
-; CHECK-NEXT: [[VAL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR24]]
-; CHECK-NEXT: ret float [[VAL]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
+; TUNIT-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @constrained_uitofp
+; TUNIT-SAME: (i32 [[ARG:%.*]]) #[[ATTR8]] {
+; TUNIT-NEXT: [[VAL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR27]]
+; TUNIT-NEXT: ret float [[VAL]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind strictfp willreturn memory(inaccessiblemem: readwrite)
+; CGSCC-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @constrained_uitofp
+; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR8]] {
+; CGSCC-NEXT: [[VAL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[ARG]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR26]]
+; CGSCC-NEXT: ret float [[VAL]]
;
%val = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %arg, metadata !"round.dynamic", metadata !"fpexcept.strict")
ret float %val
@@ -2297,7 +2309,7 @@ define float @fadd_known_positive_daz(float nofpclass(ninf nsub nnorm) %arg0, fl
define float @test_fadd_no_nan_from_no_ninf(float nofpclass(nan ninf) %arg0, float nofpclass(nan ninf) %arg1) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define nofpclass(nan) float @test_fadd_no_nan_from_no_ninf
-; CHECK-SAME: (float nofpclass(nan ninf) [[ARG0:%.*]], float nofpclass(nan ninf) [[ARG1:%.*]]) #[[ATTR:[0-9]+]] {
+; CHECK-SAME: (float nofpclass(nan ninf) [[ARG0:%.*]], float nofpclass(nan ninf) [[ARG1:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[ADD]]
;
@@ -2308,7 +2320,7 @@ define float @test_fadd_no_nan_from_no_ninf(float nofpclass(nan ninf) %arg0, flo
define float @test_fadd_no_nan_from_no_pinf(float nofpclass(nan pinf) %arg0, float nofpclass(nan pinf) %arg1) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define nofpclass(nan) float @test_fadd_no_nan_from_no_pinf
-; CHECK-SAME: (float nofpclass(nan pinf) [[ARG0:%.*]], float nofpclass(nan pinf) [[ARG1:%.*]]) #[[ATTR:[0-9]+]] {
+; CHECK-SAME: (float nofpclass(nan pinf) [[ARG0:%.*]], float nofpclass(nan pinf) [[ARG1:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[ADD]]
;
@@ -2319,7 +2331,7 @@ define float @test_fadd_no_nan_from_no_pinf(float nofpclass(nan pinf) %arg0, flo
define float @test_fadd_may_nan_from_no_pinf_no_ninf(float nofpclass(nan pinf) %arg0, float nofpclass(nan ninf) %arg1) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define float @test_fadd_may_nan_from_no_pinf_no_ninf
-; CHECK-SAME: (float nofpclass(nan pinf) [[ARG0:%.*]], float nofpclass(nan ninf) [[ARG1:%.*]]) #[[ATTR:[0-9]+]] {
+; CHECK-SAME: (float nofpclass(nan pinf) [[ARG0:%.*]], float nofpclass(nan ninf) [[ARG1:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[ADD]]
;
@@ -2330,7 +2342,7 @@ define float @test_fadd_may_nan_from_no_pinf_no_ninf(float nofpclass(nan pinf) %
define float @test_fadd_may_nan_from_no_ninf_no_pinf(float nofpclass(nan ninf) %arg0, float nofpclass(nan pinf) %arg1) {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; CHECK-LABEL: define float @test_fadd_may_nan_from_no_ninf_no_pinf
-; CHECK-SAME: (float nofpclass(nan ninf) [[ARG0:%.*]], float nofpclass(nan pinf) [[ARG1:%.*]]) #[[ATTR:[0-9]+]] {
+; CHECK-SAME: (float nofpclass(nan ninf) [[ARG0:%.*]], float nofpclass(nan pinf) [[ARG1:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[ADD]]
;
@@ -3643,13 +3655,21 @@ define float @fadd_double_no_zero__output_only_is_dynamic(float noundef nofpclas
; Implies return must be 0
define float @assume_select_condition_not_nan(float noundef %arg) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
-; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @assume_select_condition_not_nan
-; CHECK-SAME: (float noundef [[ARG:%.*]]) #[[ATTR19:[0-9]+]] {
-; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
-; CHECK-NEXT: call void @llvm.assume(i1 noundef [[ORD]]) #[[ATTR22]]
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[ORD]], float 0.000000e+00, float [[ARG]]
-; CHECK-NEXT: ret float [[SELECT]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
+; TUNIT-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @assume_select_condition_not_nan
+; TUNIT-SAME: (float noundef [[ARG:%.*]]) #[[ATTR19:[0-9]+]] {
+; TUNIT-NEXT: [[ORD:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ORD]]) #[[ATTR28:[0-9]+]]
+; TUNIT-NEXT: [[SELECT:%.*]] = select i1 [[ORD]], float 0.000000e+00, float [[ARG]]
+; TUNIT-NEXT: ret float [[SELECT]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
+; CGSCC-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @assume_select_condition_not_nan
+; CGSCC-SAME: (float noundef [[ARG:%.*]]) #[[ATTR19:[0-9]+]] {
+; CGSCC-NEXT: [[ORD:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ORD]]) #[[ATTR27:[0-9]+]]
+; CGSCC-NEXT: [[SELECT:%.*]] = select i1 [[ORD]], float 0.000000e+00, float [[ARG]]
+; CGSCC-NEXT: ret float [[SELECT]]
;
%ord = fcmp ord float %arg, 0.0
call void @llvm.assume(i1 %ord)
@@ -3658,13 +3678,21 @@ define float @assume_select_condition_not_nan(float noundef %arg) {
}
define float @assume_select_condition_not_nan_commute(float noundef %arg) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
-; CHECK-LABEL: define noundef nofpclass(inf nzero sub norm) float @assume_select_condition_not_nan_commute
-; CHECK-SAME: (float noundef [[ARG:%.*]]) #[[ATTR19]] {
-; CHECK-NEXT: [[UNO:%.*]] = fcmp uno float [[ARG]], 0.000000e+00
-; CHECK-NEXT: call void @llvm.assume(i1 noundef [[UNO]]) #[[ATTR22]]
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[UNO]], float [[ARG]], float 0.000000e+00
-; CHECK-NEXT: ret float [[SELECT]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
+; TUNIT-LABEL: define noundef nofpclass(inf nzero sub norm) float @assume_select_condition_not_nan_commute
+; TUNIT-SAME: (float noundef [[ARG:%.*]]) #[[ATTR19]] {
+; TUNIT-NEXT: [[UNO:%.*]] = fcmp uno float [[ARG]], 0.000000e+00
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[UNO]]) #[[ATTR28]]
+; TUNIT-NEXT: [[SELECT:%.*]] = select i1 [[UNO]], float [[ARG]], float 0.000000e+00
+; TUNIT-NEXT: ret float [[SELECT]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
+; CGSCC-LABEL: define noundef nofpclass(inf nzero sub norm) float @assume_select_condition_not_nan_commute
+; CGSCC-SAME: (float noundef [[ARG:%.*]]) #[[ATTR19]] {
+; CGSCC-NEXT: [[UNO:%.*]] = fcmp uno float [[ARG]], 0.000000e+00
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[UNO]]) #[[ATTR27]]
+; CGSCC-NEXT: [[SELECT:%.*]] = select i1 [[UNO]], float [[ARG]], float 0.000000e+00
+; CGSCC-NEXT: ret float [[SELECT]]
;
%uno = fcmp uno float %arg, 0.0
call void @llvm.assume(i1 %uno)
@@ -3674,13 +3702,21 @@ define float @assume_select_condition_not_nan_commute(float noundef %arg) {
; Implies no return nan
define float @assume_load(ptr %ptr) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)
-; CHECK-LABEL: define nofpclass(nan) float @assume_load
-; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[PTR:%.*]]) #[[ATTR20:[0-9]+]] {
-; CHECK-NEXT: [[VAL:%.*]] = load float, ptr [[PTR]], align 4
-; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[VAL]], 0.000000e+00
-; CHECK-NEXT: call void @llvm.assume(i1 noundef [[ORD]]) #[[ATTR22]]
-; CHECK-NEXT: ret float [[VAL]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)
+; TUNIT-LABEL: define nofpclass(nan) float @assume_load
+; TUNIT-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[PTR:%.*]]) #[[ATTR20:[0-9]+]] {
+; TUNIT-NEXT: [[VAL:%.*]] = load float, ptr [[PTR]], align 4
+; TUNIT-NEXT: [[ORD:%.*]] = fcmp ord float [[VAL]], 0.000000e+00
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ORD]]) #[[ATTR28]]
+; TUNIT-NEXT: ret float [[VAL]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)
+; CGSCC-LABEL: define nofpclass(nan) float @assume_load
+; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[PTR:%.*]]) #[[ATTR20:[0-9]+]] {
+; CGSCC-NEXT: [[VAL:%.*]] = load float, ptr [[PTR]], align 4
+; CGSCC-NEXT: [[ORD:%.*]] = fcmp ord float [[VAL]], 0.000000e+00
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ORD]]) #[[ATTR27]]
+; CGSCC-NEXT: ret float [[VAL]]
;
%val = load float, ptr %ptr
%ord = fcmp ord float %val, 0.0
@@ -3690,12 +3726,19 @@ define float @assume_load(ptr %ptr) {
; FIXME: Why is this not working?
define float @assume_returned_arg(float noundef %arg) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
-; CHECK-LABEL: define noundef float @assume_returned_arg
-; CHECK-SAME: (float noundef returned [[ARG:%.*]]) #[[ATTR19]] {
-; CHECK-NEXT: [[ORD:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
-; CHECK-NEXT: call void @llvm.assume(i1 noundef [[ORD]]) #[[ATTR22]]
-; CHECK-NEXT: ret float [[ARG]]
+; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
+; TUNIT-LABEL: define noundef float @assume_returned_arg
+; TUNIT-SAME: (float noundef returned [[ARG:%.*]]) #[[ATTR19]] {
+; TUNIT-NEXT: [[ORD:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ORD]]) #[[ATTR28]]
+; TUNIT-NEXT: ret float [[ARG]]
+;
+; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
+; CGSCC-LABEL: define noundef float @assume_returned_arg
+; CGSCC-SAME: (float noundef returned [[ARG:%.*]]) #[[ATTR19]] {
+; CGSCC-NEXT: [[ORD:%.*]] = fcmp ord float [[ARG]], 0.000000e+00
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ORD]]) #[[ATTR27]]
+; CGSCC-NEXT: ret float [[ARG]]
;
%ord = fcmp ord float %arg, 0.0
call void @llvm.assume(i1 %ord)
diff --git a/llvm/test/Transforms/Attributor/nofree.ll b/llvm/test/Transforms/Attributor/nofree.ll
index 94aa79aa327f4..4a059fd1adf5f 100644
--- a/llvm/test/Transforms/Attributor/nofree.ll
+++ b/llvm/test/Transforms/Attributor/nofree.ll
@@ -255,7 +255,7 @@ define float @call_floor2(float %a) #0 {
; CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable
; CHECK-LABEL: define {{[^@]+}}@call_floor2
; CHECK-SAME: (float [[A:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[C:%.*]] = tail call nofpclass(sub) float @llvm.floor.f32(float [[A]]) #[[ATTR14:[0-9]+]]
+; CHECK-NEXT: [[C:%.*]] = tail call nofpclass(sub) float @llvm.floor.f32(float [[A]]) #[[ATTR13:[0-9]+]]
; CHECK-NEXT: ret float [[C]]
;
%c = tail call float @llvm.floor.f32(float %a)
@@ -297,12 +297,12 @@ define void @f2() #0 {
; TEST 12 NoFree argument - positive.
define double @test12(ptr nocapture readonly %a) {
-; CHECK: Function Attrs: nofree nounwind
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@test12
-; CHECK-SAME: (ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR7:[0-9]+]] {
+; CHECK-SAME: (ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[A]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = tail call double @cos(double [[TMP0]]) #[[ATTR8:[0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call double @cos(double [[TMP0]]) #[[ATTR2]]
; CHECK-NEXT: ret double [[CALL]]
;
entry:
@@ -352,7 +352,7 @@ define void @nonnull_assume_pos(ptr %arg1, ptr %arg2, ptr %arg3, ptr %arg4) {
;
; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_pos
; CHECK-SAME: (ptr nofree [[ARG1:%.*]], ptr [[ARG2:%.*]], ptr nofree [[ARG3:%.*]], ptr [[ARG4:%.*]]) {
-; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR15:[0-9]+]] [ "nofree"(ptr [[ARG1]]), "nofree"(ptr [[ARG3]]) ]
+; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14:[0-9]+]] [ "nofree"(ptr [[ARG1]]), "nofree"(ptr [[ARG3]]) ]
; CHECK-NEXT: call void @unknown(ptr nofree [[ARG1]], ptr [[ARG2]], ptr nofree [[ARG3]], ptr [[ARG4]])
; CHECK-NEXT: ret void
;
@@ -426,7 +426,7 @@ define void @nonnull_assume_call(ptr %arg1, ptr %arg2, ptr %arg3, ptr %arg4) {
define weak void @implied_nofree1() readnone {
; CHECK: Function Attrs: nosync memory(none)
; CHECK-LABEL: define {{[^@]+}}@implied_nofree1
-; CHECK-SAME: () #[[ATTR9:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR8:[0-9]+]] {
; CHECK-NEXT: ret void
;
ret void
@@ -435,7 +435,7 @@ define weak void @implied_nofree1() readnone {
define weak void @implied_nofree2() readonly {
; CHECK: Function Attrs: nosync memory(read)
; CHECK-LABEL: define {{[^@]+}}@implied_nofree2
-; CHECK-SAME: () #[[ATTR10:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR9:[0-9]+]] {
; CHECK-NEXT: ret void
;
ret void
@@ -458,7 +458,7 @@ define weak void @implied_nofree4(ptr readonly %a) {
define weak void @implied_nofree5(ptr %a) readonly {
; CHECK: Function Attrs: nosync memory(read)
; CHECK-LABEL: define {{[^@]+}}@implied_nofree5
-; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR10]] {
+; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR9]] {
; CHECK-NEXT: ret void
;
ret void
@@ -466,7 +466,7 @@ define weak void @implied_nofree5(ptr %a) readonly {
define weak void @implied_nofree6(ptr %a) nofree {
; CHECK: Function Attrs: nofree
; CHECK-LABEL: define {{[^@]+}}@implied_nofree6
-; CHECK-SAME: (ptr nofree [[A:%.*]]) #[[ATTR11:[0-9]+]] {
+; CHECK-SAME: (ptr nofree [[A:%.*]]) #[[ATTR10:[0-9]+]] {
; CHECK-NEXT: ret void
;
ret void
@@ -490,15 +490,14 @@ attributes #2 = { nobuiltin nounwind }
; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree noinline nosync nounwind willreturn memory(none) uwtable }
; TUNIT: attributes #[[ATTR5:[0-9]+]] = { nofree noinline nounwind memory(none) uwtable }
; TUNIT: attributes #[[ATTR6:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
-; TUNIT: attributes #[[ATTR7]] = { nofree nounwind }
-; TUNIT: attributes #[[ATTR8]] = { nobuiltin nofree nounwind }
-; TUNIT: attributes #[[ATTR9]] = { nosync memory(none) }
-; TUNIT: attributes #[[ATTR10]] = { nosync memory(read) }
-; TUNIT: attributes #[[ATTR11]] = { nofree }
-; TUNIT: attributes #[[ATTR12:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
-; TUNIT: attributes #[[ATTR13:[0-9]+]] = { nounwind willreturn }
-; TUNIT: attributes #[[ATTR14]] = { nofree nosync willreturn }
-; TUNIT: attributes #[[ATTR15]] = { nofree willreturn memory(write) }
+; TUNIT: attributes #[[ATTR7:[0-9]+]] = { nobuiltin nofree nounwind }
+; TUNIT: attributes #[[ATTR8]] = { nosync memory(none) }
+; TUNIT: attributes #[[ATTR9]] = { nosync memory(read) }
+; TUNIT: attributes #[[ATTR10]] = { nofree }
+; TUNIT: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
+; TUNIT: attributes #[[ATTR12:[0-9]+]] = { nounwind willreturn }
+; TUNIT: attributes #[[ATTR13]] = { nofree nosync willreturn }
+; TUNIT: attributes #[[ATTR14]] = { willreturn memory(write) }
;.
; CGSCC: attributes #[[ATTR0]] = { nounwind }
; CGSCC: attributes #[[ATTR1]] = { noinline nounwind uwtable }
@@ -507,13 +506,12 @@ attributes #2 = { nobuiltin nounwind }
; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nofree noinline nounwind memory(none) uwtable }
; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree noinline nosync nounwind willreturn memory(none) uwtable }
; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
-; CGSCC: attributes #[[ATTR7]] = { nofree nounwind }
-; CGSCC: attributes #[[ATTR8]] = { nobuiltin nofree nounwind }
-; CGSCC: attributes #[[ATTR9]] = { nosync memory(none) }
-; CGSCC: attributes #[[ATTR10]] = { nosync memory(read) }
-; CGSCC: attributes #[[ATTR11]] = { nofree }
-; CGSCC: attributes #[[ATTR12:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
-; CGSCC: attributes #[[ATTR13:[0-9]+]] = { nounwind willreturn }
-; CGSCC: attributes #[[ATTR14]] = { nofree nosync willreturn }
-; CGSCC: attributes #[[ATTR15]] = { nofree willreturn memory(write) }
+; CGSCC: attributes #[[ATTR7:[0-9]+]] = { nobuiltin nofree nounwind }
+; CGSCC: attributes #[[ATTR8]] = { nosync memory(none) }
+; CGSCC: attributes #[[ATTR9]] = { nosync memory(read) }
+; CGSCC: attributes #[[ATTR10]] = { nofree }
+; CGSCC: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
+; CGSCC: attributes #[[ATTR12:[0-9]+]] = { nounwind willreturn }
+; CGSCC: attributes #[[ATTR13]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR14]] = { willreturn memory(write) }
;.
diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index 93690ddef6634..0d48414b530ff 100644
--- a/llvm/test/Transforms/Attributor/nonnull.ll
+++ b/llvm/test/Transforms/Attributor/nonnull.ll
@@ -294,7 +294,7 @@ define ptr @test10(ptr %a, i64 %n) {
; FIXME: missing nonnull
define ptr @test11(ptr) local_unnamed_addr {
; CHECK-LABEL: define {{[^@]+}}@test11
-; CHECK-SAME: (ptr [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-SAME: (ptr nofree [[TMP0:%.*]]) local_unnamed_addr {
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null
; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
; CHECK: 3:
@@ -843,7 +843,7 @@ f:
define i8 @parent6(ptr %a, ptr %b) {
; CHECK-LABEL: define {{[^@]+}}@parent6
-; CHECK-SAME: (ptr [[A:%.*]], ptr nofree noundef [[B:%.*]]) {
+; CHECK-SAME: (ptr [[A:%.*]], ptr noundef [[B:%.*]]) {
; CHECK-NEXT: [[C:%.*]] = load volatile i8, ptr [[B]], align 1
; CHECK-NEXT: call void @use1nonnull(ptr nonnull [[A]])
; CHECK-NEXT: ret i8 [[C]]
@@ -1425,14 +1425,14 @@ define void @nonnull_assume_pos(ptr %arg) {
;
; TUNIT-LABEL: define {{[^@]+}}@nonnull_assume_pos
; TUNIT-SAME: (ptr nofree nonnull readnone captures(none) [[ARG:%.*]]) {
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16]] [ "nonnull"(ptr [[ARG]]) ]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR20:[0-9]+]] [ "nonnull"(ptr [[ARG]]) ]
; TUNIT-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[ARG]]) #[[ATTR5]]
; TUNIT-NEXT: [[TMP1:%.*]] = call ptr @unknown()
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define {{[^@]+}}@nonnull_assume_pos
; CGSCC-SAME: (ptr nofree nonnull readnone captures(none) [[ARG:%.*]]) {
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16]] [ "nonnull"(ptr [[ARG]]) ]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR21:[0-9]+]] [ "nonnull"(ptr [[ARG]]) ]
; CGSCC-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[ARG]]) #[[ATTR4]]
; CGSCC-NEXT: [[TMP1:%.*]] = call ptr @unknown()
; CGSCC-NEXT: ret void
@@ -1553,15 +1553,15 @@ merge:
define void @phi_caller(ptr %p) {
; TUNIT: Function Attrs: nounwind
; TUNIT-LABEL: define {{[^@]+}}@phi_caller
-; TUNIT-SAME: (ptr nofree [[P:%.*]]) #[[ATTR5]] {
-; TUNIT-NEXT: [[C:%.*]] = call nonnull ptr @phi(ptr noalias nofree readnone [[P]]) #[[ATTR20:[0-9]+]]
+; TUNIT-SAME: (ptr [[P:%.*]]) #[[ATTR5]] {
+; TUNIT-NEXT: [[C:%.*]] = call nonnull ptr @phi(ptr noalias nofree readnone [[P]]) #[[ATTR21:[0-9]+]]
; TUNIT-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[C]]) #[[ATTR5]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nounwind
; CGSCC-LABEL: define {{[^@]+}}@phi_caller
-; CGSCC-SAME: (ptr nofree [[P:%.*]]) #[[ATTR4]] {
-; CGSCC-NEXT: [[C:%.*]] = call nonnull ptr @phi(ptr noalias nofree readnone [[P]]) #[[ATTR21:[0-9]+]]
+; CGSCC-SAME: (ptr [[P:%.*]]) #[[ATTR4]] {
+; CGSCC-NEXT: [[C:%.*]] = call nonnull ptr @phi(ptr noalias nofree readnone [[P]]) #[[ATTR22:[0-9]+]]
; CGSCC-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[C]]) #[[ATTR4]]
; CGSCC-NEXT: ret void
;
@@ -1593,15 +1593,15 @@ NULL:
define void @multi_ret_caller(ptr %p) {
; TUNIT: Function Attrs: nounwind
; TUNIT-LABEL: define {{[^@]+}}@multi_ret_caller
-; TUNIT-SAME: (ptr nofree [[P:%.*]]) #[[ATTR5]] {
-; TUNIT-NEXT: [[C:%.*]] = call nonnull ptr @multi_ret(ptr noalias nofree readnone [[P]]) #[[ATTR20]]
+; TUNIT-SAME: (ptr [[P:%.*]]) #[[ATTR5]] {
+; TUNIT-NEXT: [[C:%.*]] = call nonnull ptr @multi_ret(ptr noalias nofree readnone [[P]]) #[[ATTR21]]
; TUNIT-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[C]]) #[[ATTR5]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nounwind
; CGSCC-LABEL: define {{[^@]+}}@multi_ret_caller
-; CGSCC-SAME: (ptr nofree [[P:%.*]]) #[[ATTR4]] {
-; CGSCC-NEXT: [[C:%.*]] = call nonnull ptr @multi_ret(ptr noalias nofree readnone [[P]]) #[[ATTR21]]
+; CGSCC-SAME: (ptr [[P:%.*]]) #[[ATTR4]] {
+; CGSCC-NEXT: [[C:%.*]] = call nonnull ptr @multi_ret(ptr noalias nofree readnone [[P]]) #[[ATTR22]]
; CGSCC-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[C]]) #[[ATTR4]]
; CGSCC-NEXT: ret void
;
@@ -1660,7 +1660,8 @@ attributes #1 = { nounwind willreturn}
; TUNIT: attributes #[[ATTR17]] = { nofree nosync nounwind memory(read) }
; TUNIT: attributes #[[ATTR18]] = { nosync willreturn memory(read) }
; TUNIT: attributes #[[ATTR19]] = { nofree nosync willreturn memory(read) }
-; TUNIT: attributes #[[ATTR20]] = { nofree nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR20]] = { willreturn memory(write) }
+; TUNIT: attributes #[[ATTR21]] = { nosync nounwind willreturn memory(none) }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
@@ -1683,7 +1684,8 @@ attributes #1 = { nounwind willreturn}
; CGSCC: attributes #[[ATTR18]] = { nosync willreturn memory(read) }
; CGSCC: attributes #[[ATTR19]] = { nofree nosync willreturn }
; CGSCC: attributes #[[ATTR20]] = { nofree nosync willreturn memory(read) }
-; CGSCC: attributes #[[ATTR21]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR21]] = { willreturn memory(write) }
+; CGSCC: attributes #[[ATTR22]] = { willreturn }
;.
; TUNIT: [[META0]] = !{}
;.
diff --git a/llvm/test/Transforms/Attributor/nosync.ll b/llvm/test/Transforms/Attributor/nosync.ll
index 8ae50c812b739..49b02beb8d181 100644
--- a/llvm/test/Transforms/Attributor/nosync.ll
+++ b/llvm/test/Transforms/Attributor/nosync.ll
@@ -86,7 +86,7 @@ define void @store_monotonic(ptr nocapture %arg) norecurse nounwind uwtable {
; }
define i32 @load_acquire(ptr nocapture readonly %arg) norecurse nounwind uwtable {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) uwtable
; CHECK-LABEL: define {{[^@]+}}@load_acquire
; CHECK-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: [[I:%.*]] = load atomic i32, ptr [[ARG]] acquire, align 4
@@ -103,9 +103,9 @@ define i32 @load_acquire(ptr nocapture readonly %arg) norecurse nounwind uwtable
; }
define void @load_release(ptr nocapture %arg) norecurse nounwind uwtable {
-; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite) uwtable
+; CHECK: Function Attrs: norecurse nounwind memory(argmem: readwrite) uwtable
; CHECK-LABEL: define {{[^@]+}}@load_release
-; CHECK-SAME: (ptr nofree noundef writeonly align 4 captures(none) [[ARG:%.*]]) #[[ATTR3:[0-9]+]] {
+; CHECK-SAME: (ptr noundef writeonly align 4 captures(none) [[ARG:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: store atomic volatile i32 10, ptr [[ARG]] release, align 4
; CHECK-NEXT: ret void
;
@@ -116,9 +116,9 @@ define void @load_release(ptr nocapture %arg) norecurse nounwind uwtable {
; TEST 6 - negative volatile, relaxed atomic
define void @load_volatile_release(ptr nocapture %arg) norecurse nounwind uwtable {
-; CHECK: Function Attrs: nofree norecurse nounwind memory(argmem: readwrite) uwtable
+; CHECK: Function Attrs: norecurse nounwind memory(argmem: readwrite) uwtable
; CHECK-LABEL: define {{[^@]+}}@load_volatile_release
-; CHECK-SAME: (ptr nofree noundef writeonly align 4 captures(none) [[ARG:%.*]]) #[[ATTR3]] {
+; CHECK-SAME: (ptr noundef writeonly align 4 captures(none) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: store atomic volatile i32 10, ptr [[ARG]] release, align 4
; CHECK-NEXT: ret void
;
@@ -247,7 +247,7 @@ define void @scc2(ptr %arg) noinline nounwind uwtable {
%"struct.std::__atomic_base" = type { i8 }
define void @foo1(ptr %arg, ptr %arg1) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@foo1
; CHECK-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ARG:%.*]], ptr nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[ARG1:%.*]]) #[[ATTR8:[0-9]+]] {
; CHECK-NEXT: store i32 100, ptr [[ARG]], align 4
@@ -262,7 +262,7 @@ define void @foo1(ptr %arg, ptr %arg1) {
}
define void @bar(ptr %arg, ptr %arg1) {
-; CHECK: Function Attrs: nofree norecurse nounwind
+; CHECK: Function Attrs: norecurse nounwind
; CHECK-LABEL: define {{[^@]+}}@bar
; CHECK-SAME: (ptr nofree readnone captures(none) [[ARG:%.*]], ptr nofree nonnull readonly captures(none) dereferenceable(1) [[ARG1:%.*]]) #[[ATTR9:[0-9]+]] {
; CHECK-NEXT: br label [[BB2:%.*]]
@@ -470,14 +470,14 @@ define void @nosync_convergent_callee_test() {
;.
; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind optsize ssp willreturn memory(none) uwtable }
; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable }
-; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable }
-; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nounwind memory(argmem: readwrite) uwtable }
+; TUNIT: attributes #[[ATTR2]] = { mustprogress norecurse nounwind willreturn memory(argmem: readwrite) uwtable }
+; TUNIT: attributes #[[ATTR3]] = { norecurse nounwind memory(argmem: readwrite) uwtable }
; TUNIT: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind memory(argmem: readwrite) uwtable }
; TUNIT: attributes #[[ATTR5]] = { noinline nosync nounwind uwtable }
; TUNIT: attributes #[[ATTR6]] = { noinline nounwind uwtable }
; TUNIT: attributes #[[ATTR7]] = { nofree noinline nosync nounwind memory(argmem: readwrite) uwtable }
-; TUNIT: attributes #[[ATTR8]] = { mustprogress nofree norecurse nounwind willreturn }
-; TUNIT: attributes #[[ATTR9]] = { nofree norecurse nounwind }
+; TUNIT: attributes #[[ATTR8]] = { mustprogress norecurse nounwind willreturn }
+; TUNIT: attributes #[[ATTR9]] = { norecurse nounwind }
; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind }
; TUNIT: attributes #[[ATTR12:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
@@ -498,14 +498,14 @@ define void @nosync_convergent_callee_test() {
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind optsize ssp willreturn memory(none) uwtable }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable }
-; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) uwtable }
-; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nounwind memory(argmem: readwrite) uwtable }
+; CGSCC: attributes #[[ATTR2]] = { mustprogress norecurse nounwind willreturn memory(argmem: readwrite) uwtable }
+; CGSCC: attributes #[[ATTR3]] = { norecurse nounwind memory(argmem: readwrite) uwtable }
; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind memory(argmem: readwrite) uwtable }
; CGSCC: attributes #[[ATTR5]] = { noinline nosync nounwind uwtable }
; CGSCC: attributes #[[ATTR6]] = { noinline nounwind uwtable }
; CGSCC: attributes #[[ATTR7]] = { nofree noinline nosync nounwind memory(argmem: readwrite) uwtable }
-; CGSCC: attributes #[[ATTR8]] = { mustprogress nofree norecurse nounwind willreturn }
-; CGSCC: attributes #[[ATTR9]] = { nofree norecurse nounwind }
+; CGSCC: attributes #[[ATTR8]] = { mustprogress norecurse nounwind willreturn }
+; CGSCC: attributes #[[ATTR9]] = { norecurse nounwind }
; CGSCC: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind }
; CGSCC: attributes #[[ATTR12:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll
index 38f8a829cf419..c4d51b7956560 100644
--- a/llvm/test/Transforms/Attributor/range.ll
+++ b/llvm/test/Transforms/Attributor/range.ll
@@ -82,7 +82,7 @@ define void @test0-icmp-check(ptr %p){
; ret = [0, 10)
; TUNIT-LABEL: define {{[^@]+}}@test0-icmp-check
; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) {
-; TUNIT-NEXT: [[RET:%.*]] = tail call range(i32 0, 10) i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3]]
+; TUNIT-NEXT: [[RET:%.*]] = tail call range(i32 0, 10) i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR4:[0-9]+]]
; TUNIT-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
; TUNIT-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
; TUNIT-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
@@ -149,7 +149,7 @@ define void @test0-icmp-check(ptr %p){
;
; CGSCC-LABEL: define {{[^@]+}}@test0-icmp-check
; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) {
-; CGSCC-NEXT: [[RET:%.*]] = tail call i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]
+; CGSCC-NEXT: [[RET:%.*]] = tail call i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR6:[0-9]+]]
; CGSCC-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
; CGSCC-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
; CGSCC-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
@@ -494,7 +494,7 @@ f:
define void @f1(i32){
; TUNIT-LABEL: define {{[^@]+}}@f1
; TUNIT-SAME: (i32 [[TMP0:%.*]]) {
-; TUNIT-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR4:[0-9]+]]
+; TUNIT-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR5:[0-9]+]]
; TUNIT-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
; TUNIT-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
; TUNIT: 4:
@@ -505,7 +505,7 @@ define void @f1(i32){
;
; CGSCC-LABEL: define {{[^@]+}}@f1
; CGSCC-SAME: (i32 [[TMP0:%.*]]) {
-; CGSCC-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR6:[0-9]+]]
+; CGSCC-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR7:[0-9]+]]
; CGSCC-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
; CGSCC-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
; CGSCC: 4:
@@ -580,14 +580,14 @@ define dso_local i32 @test4-g1(i32 %u) {
; TUNIT-LABEL: define {{[^@]+}}@test4-g1
; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR4]]
+; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR5]]
; TUNIT-NEXT: ret i32 [[CALL]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@test4-g1
; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3:[0-9]+]] {
; CGSCC-NEXT: entry:
-; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR7:[0-9]+]]
+; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR8:[0-9]+]]
; CGSCC-NEXT: ret i32 [[CALL]]
;
; FIXME: %call should have range [0, inf]
@@ -658,14 +658,14 @@ define dso_local i32 @test4-g2(i32 %u) {
; TUNIT-LABEL: define {{[^@]+}}@test4-g2
; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[CALL:%.*]] = tail call range(i32 1, -2147483648) i32 @test4-f2(i32 [[U]]) #[[ATTR4]]
+; TUNIT-NEXT: [[CALL:%.*]] = tail call range(i32 1, -2147483648) i32 @test4-f2(i32 [[U]]) #[[ATTR5]]
; TUNIT-NEXT: ret i32 [[CALL]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@test4-g2
; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: entry:
-; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR7]]
+; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR8]]
; CGSCC-NEXT: ret i32 [[CALL]]
;
entry:
@@ -1006,10 +1006,10 @@ define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, ptr %dpa, p
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@fcmp_caller
; TUNIT-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR1]] {
-; TUNIT-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR4]]
-; TUNIT-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR4]]
-; TUNIT-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR4]]
-; TUNIT-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR4]]
+; TUNIT-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR5]]
+; TUNIT-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR5]]
+; TUNIT-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR5]]
+; TUNIT-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR5]]
; TUNIT-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
; TUNIT-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
; TUNIT-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
@@ -1018,10 +1018,10 @@ define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, ptr %dpa, p
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@fcmp_caller
; CGSCC-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR7]]
-; CGSCC-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR7]]
-; CGSCC-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR7]]
-; CGSCC-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR7]]
+; CGSCC-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR8]]
+; CGSCC-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR8]]
+; CGSCC-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR8]]
+; CGSCC-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR8]]
; CGSCC-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
; CGSCC-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
; CGSCC-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
@@ -1074,7 +1074,7 @@ define i8 @undef_collapse_1() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_1
; CGSCC-SAME: () #[[ATTR3]] {
-; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_undef() #[[ATTR7]]
+; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_undef() #[[ATTR8]]
; CGSCC-NEXT: [[S:%.*]] = shl i8 [[C]], 2
; CGSCC-NEXT: ret i8 [[S]]
;
@@ -1093,7 +1093,7 @@ define i8 @undef_collapse_2() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_2
; CGSCC-SAME: () #[[ATTR3]] {
-; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_two() #[[ATTR7]]
+; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_two() #[[ATTR8]]
; CGSCC-NEXT: [[S:%.*]] = shl i8 undef, [[C]]
; CGSCC-NEXT: ret i8 [[S]]
;
@@ -1112,8 +1112,8 @@ define i8 @undef_collapse_caller() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_caller
; CGSCC-SAME: () #[[ATTR3]] {
-; CGSCC-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR7]]
-; CGSCC-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR7]]
+; CGSCC-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR8]]
+; CGSCC-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR8]]
; CGSCC-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]]
; CGSCC-NEXT: ret i8 [[A]]
;
@@ -1144,8 +1144,8 @@ define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@callee_range_1
; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR1]] {
-; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]
-; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]
+; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR5]]
+; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR5]]
; TUNIT-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]
; TUNIT-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
; TUNIT-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4
@@ -1156,8 +1156,8 @@ define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@callee_range_1
; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]
-; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]
+; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR8]]
+; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR8]]
; CGSCC-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]
; CGSCC-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
; CGSCC-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4
@@ -1180,8 +1180,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@callee_range_2
; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] {
-; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]
-; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]
+; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR5]]
+; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR5]]
; TUNIT-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
; TUNIT-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
; TUNIT-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
@@ -1191,8 +1191,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@callee_range_2
; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]
-; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]
+; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR8]]
+; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR8]]
; CGSCC-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
; CGSCC-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
; CGSCC-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
@@ -1247,7 +1247,7 @@ define i1 @ctx_adjustment(i32 %V) {
; CGSCC: if.true:
; CGSCC-NEXT: br label [[END:%.*]]
; CGSCC: if.false:
-; CGSCC-NEXT: [[CALL:%.*]] = call i32 @ret100() #[[ATTR7]]
+; CGSCC-NEXT: [[CALL:%.*]] = call i32 @ret100() #[[ATTR8]]
; CGSCC-NEXT: br label [[END]]
; CGSCC: end:
; CGSCC-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ [[CALL]], [[IF_FALSE]] ]
@@ -1292,10 +1292,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; TUNIT-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
-; TUNIT-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR4]]
+; TUNIT-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR5]]
; TUNIT-NEXT: ret i32 [[RET1]]
; TUNIT: f:
-; TUNIT-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR4]]
+; TUNIT-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR5]]
; TUNIT-NEXT: ret i32 [[RET2]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
@@ -1304,10 +1304,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; CGSCC-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
-; CGSCC-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR7]]
+; CGSCC-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR8]]
; CGSCC-NEXT: ret i32 [[RET1]]
; CGSCC: f:
-; CGSCC-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR7]]
+; CGSCC-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR8]]
; CGSCC-NEXT: ret i32 [[RET2]]
;
%c = select i1 %d, i1 true, i1 false
@@ -1352,10 +1352,10 @@ define i1 @check_divided_range(i32 %arg) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@check_divided_range
; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR7]]
-; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR7]]
-; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR7]]
-; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR7]]
+; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR8]]
+; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR8]]
+; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR8]]
+; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR8]]
; CGSCC-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; CGSCC-NEXT: ret i1 [[RET]]
;
@@ -1399,10 +1399,10 @@ define i1 @check_casted_range(i1 %c) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@check_casted_range
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR7]]
-; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR7]]
+; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR8]]
+; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR8]]
; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
-; CGSCC-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR7]]
+; CGSCC-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR8]]
; CGSCC-NEXT: ret i1 [[RET]]
;
%csret1 = call i32 @cast_and_return(i1 true)
@@ -1487,8 +1487,8 @@ define i1 @propagate_range1(i32 %c){
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@propagate_range1
; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 noundef [[C]]) #[[ATTR7]]
-; CGSCC-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR7]]
+; CGSCC-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 noundef [[C]]) #[[ATTR8]]
+; CGSCC-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR8]]
; CGSCC-NEXT: ret i1 [[TRUE]]
;
%csret = call i32 @less_than_100_1(i32 %c)
@@ -1603,20 +1603,20 @@ define i1 @propagate_range2(i32 %c) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@propagate_range2
; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
-; TUNIT-NEXT: [[CSRET1:%.*]] = call noundef i32 @less_than_100_2(i32 noundef 0) #[[ATTR4]]
-; TUNIT-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR4]]
-; TUNIT-NEXT: [[CSRET2:%.*]] = call noundef i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR4]]
-; TUNIT-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR4]]
+; TUNIT-NEXT: [[CSRET1:%.*]] = call noundef i32 @less_than_100_2(i32 noundef 0) #[[ATTR5]]
+; TUNIT-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR5]]
+; TUNIT-NEXT: [[CSRET2:%.*]] = call noundef i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR5]]
+; TUNIT-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR5]]
; TUNIT-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; TUNIT-NEXT: ret i1 [[TRUE]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@propagate_range2
; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR7]]
-; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR7]]
-; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR7]]
-; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR7]]
+; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR8]]
+; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR8]]
+; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR8]]
+; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR8]]
; CGSCC-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; CGSCC-NEXT: ret i1 [[TRUE]]
;
@@ -1653,7 +1653,7 @@ define i1 @context(ptr %p) {
; TUNIT-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]
; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
-; TUNIT-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR4]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR5]]
; TUNIT-NEXT: ret i1 [[R]]
; TUNIT: f:
; TUNIT-NEXT: ret i1 false
@@ -1665,7 +1665,7 @@ define i1 @context(ptr %p) {
; CGSCC-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]
; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
-; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @non_zero(i8 [[L]]) #[[ATTR7]]
+; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @non_zero(i8 [[L]]) #[[ATTR8]]
; CGSCC-NEXT: ret i1 [[R]]
; CGSCC: f:
; CGSCC-NEXT: ret i1 false
@@ -1800,7 +1800,8 @@ declare void @barney(i32 signext, i32 signext)
; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(none) }
; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(read) }
-; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR4]] = { nosync nounwind willreturn memory(read) }
+; TUNIT: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn memory(none) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: read) }
@@ -1808,8 +1809,9 @@ declare void @barney(i32 signext, i32 signext)
; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind memory(none) }
; CGSCC: attributes #[[ATTR5]] = { nofree willreturn memory(read) }
-; CGSCC: attributes #[[ATTR6]] = { nofree willreturn }
-; CGSCC: attributes #[[ATTR7]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR6]] = { willreturn memory(read) }
+; CGSCC: attributes #[[ATTR7]] = { willreturn }
+; CGSCC: attributes #[[ATTR8]] = { nofree nosync willreturn }
;.
; TUNIT: [[RNG0]] = !{i32 0, i32 10}
; TUNIT: [[RNG1]] = !{i32 10, i32 100}
diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll
index a9cdd46b4eef7..60f660e5813ce 100644
--- a/llvm/test/Transforms/Attributor/readattrs.ll
+++ b/llvm/test/Transforms/Attributor/readattrs.ll
@@ -15,7 +15,7 @@ declare void @test1_1(ptr %x1_1, ptr readonly %y1_1, ...)
;.
define void @test1_2(ptr %x1_2, ptr %y1_2, ptr %z1_2) {
; CHECK-LABEL: define {{[^@]+}}@test1_2
-; CHECK-SAME: (ptr [[X1_2:%.*]], ptr nofree [[Y1_2:%.*]], ptr [[Z1_2:%.*]]) {
+; CHECK-SAME: (ptr [[X1_2:%.*]], ptr [[Y1_2:%.*]], ptr [[Z1_2:%.*]]) {
; CHECK-NEXT: call void (ptr, ptr, ...) @test1_1(ptr [[X1_2]], ptr nofree readonly [[Y1_2]], ptr [[Z1_2]])
; CHECK-NEXT: store i32 0, ptr @x, align 4
; CHECK-NEXT: ret void
@@ -232,7 +232,7 @@ declare void @escape_readonly_ptr(ptr %addr, ptr readonly %ptr)
;
define void @unsound_readnone(ptr %ignored, ptr %escaped_then_written) {
; CHECK-LABEL: define {{[^@]+}}@unsound_readnone
-; CHECK-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
+; CHECK-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr [[ESCAPED_THEN_WRITTEN:%.*]]) {
; CHECK-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
; CHECK-NEXT: call void @escape_readnone_ptr(ptr noundef nonnull align 8 dereferenceable(8) [[ADDR]], ptr noalias nofree readnone [[ESCAPED_THEN_WRITTEN]])
; CHECK-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
@@ -248,7 +248,7 @@ define void @unsound_readnone(ptr %ignored, ptr %escaped_then_written) {
define void @unsound_readonly(ptr %ignored, ptr %escaped_then_written) {
; CHECK-LABEL: define {{[^@]+}}@unsound_readonly
-; CHECK-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
+; CHECK-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr [[ESCAPED_THEN_WRITTEN:%.*]]) {
; CHECK-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
; CHECK-NEXT: call void @escape_readonly_ptr(ptr noundef nonnull align 8 dereferenceable(8) [[ADDR]], ptr nofree readonly [[ESCAPED_THEN_WRITTEN]])
; CHECK-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
@@ -361,14 +361,14 @@ declare void @val_use(i8 %ptr) readonly nounwind
define void @ptr_uses(ptr %ptr) {
; TUNIT: Function Attrs: nosync nounwind memory(read)
; TUNIT-LABEL: define {{[^@]+}}@ptr_uses
-; TUNIT-SAME: (ptr nofree readonly captures(none) [[PTR:%.*]]) #[[ATTR13]] {
+; TUNIT-SAME: (ptr readonly captures(none) [[PTR:%.*]]) #[[ATTR13]] {
; TUNIT-NEXT: [[CALL_PTR:%.*]] = call ptr @maybe_returned_ptr(ptr nofree readonly [[PTR]]) #[[ATTR13]]
; TUNIT-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(ptr readonly [[CALL_PTR]]) #[[ATTR13]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nosync nounwind memory(read)
; CGSCC-LABEL: define {{[^@]+}}@ptr_uses
-; CGSCC-SAME: (ptr nofree readonly captures(none) [[PTR:%.*]]) #[[ATTR14]] {
+; CGSCC-SAME: (ptr readonly captures(none) [[PTR:%.*]]) #[[ATTR14]] {
; CGSCC-NEXT: [[CALL_PTR:%.*]] = call ptr @maybe_returned_ptr(ptr nofree readonly [[PTR]]) #[[ATTR14]]
; CGSCC-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(ptr readonly [[CALL_PTR]]) #[[ATTR14]]
; CGSCC-NEXT: ret void
diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll
index d1b036e28bb29..ab80e6cbd797c 100644
--- a/llvm/test/Transforms/Attributor/undefined_behavior.ll
+++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll
@@ -179,12 +179,12 @@ define void @store_null_propagated() {
; -- AtomicRMW tests --
define void @atomicrmw_wholly_unreachable() {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable
; TUNIT-SAME: () #[[ATTR4:[0-9]+]] {
; TUNIT-NEXT: unreachable
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable
; CGSCC-SAME: () #[[ATTR6:[0-9]+]] {
; CGSCC-NEXT: unreachable
@@ -194,7 +194,7 @@ define void @atomicrmw_wholly_unreachable() {
}
define void @atomicrmw_single_bb_unreachable(i1 %cond) {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable
; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
@@ -203,7 +203,7 @@ define void @atomicrmw_single_bb_unreachable(i1 %cond) {
; TUNIT: e:
; TUNIT-NEXT: ret void
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable
; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR6]] {
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
@@ -221,13 +221,13 @@ e:
}
define void @atomicrmw_null_pointer_is_defined() null_pointer_is_valid {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn
+; TUNIT: Function Attrs: mustprogress norecurse nounwind null_pointer_is_valid willreturn
; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined
; TUNIT-SAME: () #[[ATTR5:[0-9]+]] {
; TUNIT-NEXT: [[A:%.*]] = atomicrmw add ptr null, i32 1 acquire, align 4
; TUNIT-NEXT: ret void
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn
+; CGSCC: Function Attrs: mustprogress norecurse nounwind null_pointer_is_valid willreturn
; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined
; CGSCC-SAME: () #[[ATTR7:[0-9]+]] {
; CGSCC-NEXT: [[A:%.*]] = atomicrmw add ptr null, i32 1 acquire, align 4
@@ -241,12 +241,12 @@ define void @atomicrmw_null_propagated() {
; ATTRIBUTOR-LABEL: @atomicrmw_null_propagated(
; ATTRIBUTOR-NEXT: unreachable
;
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@atomicrmw_null_propagated
; TUNIT-SAME: () #[[ATTR4]] {
; TUNIT-NEXT: unreachable
;
-; CGSCC: Function Attrs: mustprogress nofree nounwind willreturn
+; CGSCC: Function Attrs: mustprogress nounwind willreturn
; CGSCC-LABEL: define {{[^@]+}}@atomicrmw_null_propagated
; CGSCC-SAME: () #[[ATTR8:[0-9]+]] {
; CGSCC-NEXT: [[PTR:%.*]] = call noalias ptr @ret_null() #[[ATTR12:[0-9]+]]
@@ -261,12 +261,12 @@ define void @atomicrmw_null_propagated() {
; -- AtomicCmpXchg tests --
define void @atomiccmpxchg_wholly_unreachable() {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable
; TUNIT-SAME: () #[[ATTR4]] {
; TUNIT-NEXT: unreachable
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable
; CGSCC-SAME: () #[[ATTR6]] {
; CGSCC-NEXT: unreachable
@@ -276,7 +276,7 @@ define void @atomiccmpxchg_wholly_unreachable() {
}
define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable
; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
@@ -285,7 +285,7 @@ define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) {
; TUNIT: e:
; TUNIT-NEXT: ret void
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable
; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR6]] {
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
@@ -303,13 +303,13 @@ e:
}
define void @atomiccmpxchg_null_pointer_is_defined() null_pointer_is_valid {
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn
+; TUNIT: Function Attrs: mustprogress norecurse nounwind null_pointer_is_valid willreturn
; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined
; TUNIT-SAME: () #[[ATTR5]] {
; TUNIT-NEXT: [[A:%.*]] = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic, align 4
; TUNIT-NEXT: ret void
;
-; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn
+; CGSCC: Function Attrs: mustprogress norecurse nounwind null_pointer_is_valid willreturn
; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined
; CGSCC-SAME: () #[[ATTR7]] {
; CGSCC-NEXT: [[A:%.*]] = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic, align 4
@@ -323,12 +323,12 @@ define void @atomiccmpxchg_null_propagated() {
; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_propagated(
; ATTRIBUTOR-NEXT: unreachable
;
-; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated
; TUNIT-SAME: () #[[ATTR4]] {
; TUNIT-NEXT: unreachable
;
-; CGSCC: Function Attrs: mustprogress nofree nounwind willreturn
+; CGSCC: Function Attrs: mustprogress nounwind willreturn
; CGSCC-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated
; CGSCC-SAME: () #[[ATTR8]] {
; CGSCC-NEXT: [[PTR:%.*]] = call noalias ptr @ret_null() #[[ATTR12]]
@@ -1066,8 +1066,8 @@ define noundef i32 @assumed_undef_is_ok_caller(i1 %c) {
; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind memory(none) }
; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(none) }
; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write) }
-; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nounwind willreturn memory(none) }
-; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn }
+; TUNIT: attributes #[[ATTR4]] = { mustprogress norecurse nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR5]] = { mustprogress norecurse nounwind null_pointer_is_valid willreturn }
; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn memory(write) }
@@ -1078,12 +1078,12 @@ define noundef i32 @assumed_undef_is_ok_caller(i1 %c) {
; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind null_pointer_is_valid willreturn memory(write) }
; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree nosync nounwind willreturn memory(write) }
-; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nounwind willreturn memory(none) }
-; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nounwind null_pointer_is_valid willreturn }
-; CGSCC: attributes #[[ATTR8]] = { mustprogress nofree nounwind willreturn }
+; CGSCC: attributes #[[ATTR6]] = { mustprogress norecurse nounwind willreturn memory(none) }
+; CGSCC: attributes #[[ATTR7]] = { mustprogress norecurse nounwind null_pointer_is_valid willreturn }
+; CGSCC: attributes #[[ATTR8]] = { mustprogress nounwind willreturn }
; CGSCC: attributes #[[ATTR9]] = { mustprogress nofree norecurse noreturn nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
; CGSCC: attributes #[[ATTR11]] = { nofree nosync willreturn }
-; CGSCC: attributes #[[ATTR12]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR12]] = { willreturn }
; CGSCC: attributes #[[ATTR13]] = { nofree nounwind willreturn memory(write) }
;.
diff --git a/llvm/test/Transforms/Attributor/value-simplify-assume.ll b/llvm/test/Transforms/Attributor/value-simplify-assume.ll
index c1ffb599febf6..886674cd07581 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-assume.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-assume.ll
@@ -94,7 +94,7 @@ define i1 @keep_assume_3c_nr() norecurse {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8:[0-9]+]]
; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -104,7 +104,7 @@ define i1 @keep_assume_3c_nr() norecurse {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9:[0-9]+]]
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -122,7 +122,7 @@ define i1 @keep_assume_4c_nr() norecurse {
; TUNIT-SAME: () #[[ATTR2]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]
; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 true
;
@@ -131,7 +131,7 @@ define i1 @keep_assume_4c_nr() norecurse {
; CGSCC-SAME: () #[[ATTR2]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR9]]
; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 true
;
@@ -217,7 +217,7 @@ define i1 @keep_assume_3_nr(i1 %arg) norecurse {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -227,7 +227,7 @@ define i1 @keep_assume_3_nr(i1 %arg) norecurse {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9]]
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -246,7 +246,7 @@ define i1 @keep_assume_4_nr(i1 %arg) norecurse {
; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[ARG]]
;
@@ -255,7 +255,7 @@ define i1 @keep_assume_4_nr(i1 %arg) norecurse {
; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR9]]
; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[ARG]]
;
@@ -428,7 +428,7 @@ define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse {
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8:[0-9]+]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9:[0-9]+]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -446,7 +446,7 @@ define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse {
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9:[0-9]+]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10:[0-9]+]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -480,7 +480,7 @@ define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse {
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -498,7 +498,7 @@ define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse {
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -535,8 +535,8 @@ define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse {
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9:[0-9]+]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10:[0-9]+]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -550,17 +550,17 @@ define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse {
; CGSCC: t:
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10:[0-9]+]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR11:[0-9]+]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR11]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR11]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR11]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -604,8 +604,8 @@ define i1 @assume_5c_nr(i1 %cond) norecurse {
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -619,17 +619,17 @@ define i1 @assume_5c_nr(i1 %cond) norecurse {
; CGSCC: t:
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR11]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR11]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR11]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR11]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -719,7 +719,7 @@ define i1 @keep_assume_3c() {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -727,7 +727,7 @@ define i1 @keep_assume_3c() {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9]]
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -744,7 +744,7 @@ define i1 @keep_assume_4c() {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR7]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR8]]
; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L4]]
;
@@ -752,7 +752,7 @@ define i1 @keep_assume_4c() {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR8]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L4]]
;
@@ -835,7 +835,7 @@ define i1 @keep_assume_3(i1 %arg) {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -844,7 +844,7 @@ define i1 @keep_assume_3(i1 %arg) {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9]]
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -863,7 +863,7 @@ define i1 @keep_assume_4(i1 %arg) {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -872,7 +872,7 @@ define i1 @keep_assume_4(i1 %arg) {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9]]
; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -1045,7 +1045,7 @@ define i1 @assume_3(i1 %arg, i1 %cond) {
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -1063,7 +1063,7 @@ define i1 @assume_3(i1 %arg, i1 %cond) {
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -1097,7 +1097,7 @@ define i1 @assume_4(i1 %arg, i1 %cond) {
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -1115,7 +1115,7 @@ define i1 @assume_4(i1 %arg, i1 %cond) {
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -1152,8 +1152,8 @@ define i1 @assume_5(i1 %arg, i1 %cond) {
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -1167,17 +1167,17 @@ define i1 @assume_5(i1 %arg, i1 %cond) {
; CGSCC: t:
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR11]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR11]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR11]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR11]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -1221,8 +1221,8 @@ define i1 @assume_5c(i1 %cond) {
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -1236,17 +1236,17 @@ define i1 @assume_5c(i1 %cond) {
; CGSCC: t:
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR11]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR11]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR11]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR11]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -1373,8 +1373,9 @@ define void @assume_write_globals() {
; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
; TUNIT: attributes #[[ATTR7]] = { nofree willreturn memory(write) }
-; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn memory(read) }
-; TUNIT: attributes #[[ATTR9]] = { nofree willreturn }
+; TUNIT: attributes #[[ATTR8]] = { willreturn memory(write) }
+; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn memory(read) }
+; TUNIT: attributes #[[ATTR10]] = { nofree willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
@@ -1385,6 +1386,7 @@ define void @assume_write_globals() {
; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
; CGSCC: attributes #[[ATTR8]] = { nofree willreturn memory(write) }
-; CGSCC: attributes #[[ATTR9]] = { nofree willreturn memory(read) }
-; CGSCC: attributes #[[ATTR10]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR9]] = { willreturn memory(write) }
+; CGSCC: attributes #[[ATTR10]] = { nofree willreturn memory(read) }
+; CGSCC: attributes #[[ATTR11]] = { nofree willreturn }
;.
diff --git a/llvm/test/Transforms/Attributor/value-simplify-instances.ll b/llvm/test/Transforms/Attributor/value-simplify-instances.ll
index f1dbaf0563e77..f0c2d02c75977 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-instances.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-instances.ll
@@ -25,25 +25,25 @@ define internal i1 @recursive_inst_comparator(ptr %a, ptr %b) {
define internal i1 @recursive_inst_generator(i1 %c, ptr %p) {
; TUNIT-LABEL: define {{[^@]+}}@recursive_inst_generator
-; TUNIT-SAME: (i1 [[C:%.*]], ptr nofree [[P:%.*]]) {
+; TUNIT-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
; TUNIT-NEXT: [[A:%.*]] = call ptr @geti1Ptr()
; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: [[R1:%.*]] = call i1 @recursive_inst_comparator(ptr noalias nofree readnone [[A]], ptr noalias nofree readnone [[P]]) #[[ATTR7:[0-9]+]]
; TUNIT-NEXT: ret i1 [[R1]]
; TUNIT: f:
-; TUNIT-NEXT: [[R2:%.*]] = call i1 @recursive_inst_generator(i1 noundef true, ptr nofree [[A]])
+; TUNIT-NEXT: [[R2:%.*]] = call i1 @recursive_inst_generator(i1 noundef true, ptr [[A]])
; TUNIT-NEXT: ret i1 [[R2]]
;
; CGSCC-LABEL: define {{[^@]+}}@recursive_inst_generator
-; CGSCC-SAME: (i1 [[C:%.*]], ptr nofree [[P:%.*]]) {
+; CGSCC-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
; CGSCC-NEXT: [[A:%.*]] = call ptr @geti1Ptr()
; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: [[R1:%.*]] = call i1 @recursive_inst_comparator(ptr noalias nofree readnone [[A]], ptr noalias nofree readnone [[P]])
; CGSCC-NEXT: ret i1 [[R1]]
; CGSCC: f:
-; CGSCC-NEXT: [[R2:%.*]] = call i1 @recursive_inst_generator(i1 noundef true, ptr nofree [[A]])
+; CGSCC-NEXT: [[R2:%.*]] = call i1 @recursive_inst_generator(i1 noundef true, ptr [[A]])
; CGSCC-NEXT: ret i1 [[R2]]
;
%a = call ptr @geti1Ptr()
@@ -58,15 +58,10 @@ f:
; FIXME: This should *not* return true.
define i1 @recursive_inst_generator_caller(i1 %c) {
-; TUNIT-LABEL: define {{[^@]+}}@recursive_inst_generator_caller
-; TUNIT-SAME: (i1 [[C:%.*]]) {
-; TUNIT-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_generator(i1 [[C]], ptr undef)
-; TUNIT-NEXT: ret i1 [[CALL]]
-;
-; CGSCC-LABEL: define {{[^@]+}}@recursive_inst_generator_caller
-; CGSCC-SAME: (i1 [[C:%.*]]) {
-; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_generator(i1 [[C]], ptr nofree undef)
-; CGSCC-NEXT: ret i1 [[CALL]]
+; CHECK-LABEL: define {{[^@]+}}@recursive_inst_generator_caller
+; CHECK-SAME: (i1 [[C:%.*]]) {
+; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_generator(i1 [[C]], ptr undef)
+; CHECK-NEXT: ret i1 [[CALL]]
;
%call = call i1 @recursive_inst_generator(i1 %c, ptr undef)
ret i1 %call
@@ -75,14 +70,14 @@ define i1 @recursive_inst_generator_caller(i1 %c) {
; Make sure we do *not* return true.
define internal i1 @recursive_inst_compare(i1 %c, ptr %p) {
; CHECK-LABEL: define {{[^@]+}}@recursive_inst_compare
-; CHECK-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) {
+; CHECK-SAME: (i1 [[C:%.*]], ptr nofree [[P:%.*]]) {
; CHECK-NEXT: [[A:%.*]] = call ptr @geti1Ptr()
; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CHECK: t:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[A]], [[P]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK: f:
-; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare(i1 noundef true, ptr [[A]])
+; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare(i1 noundef true, ptr nofree [[A]])
; CHECK-NEXT: ret i1 [[CALL]]
;
%a = call ptr @geti1Ptr()
@@ -97,10 +92,15 @@ f:
; FIXME: This should *not* return true.
define i1 @recursive_inst_compare_caller(i1 %c) {
-; CHECK-LABEL: define {{[^@]+}}@recursive_inst_compare_caller
-; CHECK-SAME: (i1 [[C:%.*]]) {
-; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare(i1 [[C]], ptr undef)
-; CHECK-NEXT: ret i1 [[CALL]]
+; TUNIT-LABEL: define {{[^@]+}}@recursive_inst_compare_caller
+; TUNIT-SAME: (i1 [[C:%.*]]) {
+; TUNIT-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare(i1 [[C]], ptr undef)
+; TUNIT-NEXT: ret i1 [[CALL]]
+;
+; CGSCC-LABEL: define {{[^@]+}}@recursive_inst_compare_caller
+; CGSCC-SAME: (i1 [[C:%.*]]) {
+; CGSCC-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare(i1 [[C]], ptr nofree undef)
+; CGSCC-NEXT: ret i1 [[CALL]]
;
%call = call i1 @recursive_inst_compare(i1 %c, ptr undef)
ret i1 %call
@@ -158,7 +158,7 @@ define internal i8 @recursive_alloca_load_return(i1 %c, ptr %p, i8 %v) {
; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i8 0, ptr [[A]], align 1
-; TUNIT-NEXT: [[L:%.*]] = load i8, ptr [[P]], align 1
+; TUNIT-NEXT: [[L:%.*]] = load i8, ptr [[P]], align 1, !invariant.load [[META0:![0-9]+]]
; TUNIT-NEXT: ret i8 [[L]]
; TUNIT: f:
; TUNIT-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR4:[0-9]+]]
@@ -172,7 +172,7 @@ define internal i8 @recursive_alloca_load_return(i1 %c, ptr %p, i8 %v) {
; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i8 0, ptr [[A]], align 1
-; CGSCC-NEXT: [[L:%.*]] = load i8, ptr [[P]], align 1
+; CGSCC-NEXT: [[L:%.*]] = load i8, ptr [[P]], align 1, !invariant.load [[META0:![0-9]+]]
; CGSCC-NEXT: ret i8 [[L]]
; CGSCC: f:
; CGSCC-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR3:[0-9]+]]
@@ -397,7 +397,7 @@ define i32 @non_unique_phi_ops(ptr %ptr) {
; TUNIT-NEXT: [[P:%.*]] = phi i32 [ [[NON_UNIQUE:%.*]], [[F]] ], [ poison, [[ENTRY]] ]
; TUNIT-NEXT: [[ADD]] = add i32 [[I]], 1
; TUNIT-NEXT: [[G:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[I]]
-; TUNIT-NEXT: [[NON_UNIQUE_INPUT:%.*]] = load i32, ptr [[G]], align 4
+; TUNIT-NEXT: [[NON_UNIQUE_INPUT:%.*]] = load i32, ptr [[G]], align 4, !invariant.load [[META0]]
; TUNIT-NEXT: [[CMP1:%.*]] = icmp eq i32 [[I]], [[NON_UNIQUE_INPUT]]
; TUNIT-NEXT: br i1 [[CMP1]], label [[T:%.*]], label [[F]]
; TUNIT: t:
@@ -419,7 +419,7 @@ define i32 @non_unique_phi_ops(ptr %ptr) {
; CGSCC-NEXT: [[P:%.*]] = phi i32 [ [[NON_UNIQUE:%.*]], [[F]] ], [ poison, [[ENTRY]] ]
; CGSCC-NEXT: [[ADD]] = add i32 [[I]], 1
; CGSCC-NEXT: [[G:%.*]] = getelementptr i32, ptr [[PTR]], i32 [[I]]
-; CGSCC-NEXT: [[NON_UNIQUE_INPUT:%.*]] = load i32, ptr [[G]], align 4
+; CGSCC-NEXT: [[NON_UNIQUE_INPUT:%.*]] = load i32, ptr [[G]], align 4, !invariant.load [[META0]]
; CGSCC-NEXT: [[CMP1:%.*]] = icmp eq i32 [[I]], [[NON_UNIQUE_INPUT]]
; CGSCC-NEXT: br i1 [[CMP1]], label [[T:%.*]], label [[F]]
; CGSCC: t:
@@ -470,3 +470,7 @@ end:
; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; CGSCC: attributes #[[ATTR5]] = { nofree nounwind }
;.
+; TUNIT: [[META0]] = !{}
+;.
+; CGSCC: [[META0]] = !{}
+;.
diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll
index b1af38fc8a291..854f1e42efbfb 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll
@@ -34,7 +34,7 @@ declare void @harmless_use(ptr nocapture readonly) nofree norecurse nosync nounw
; CHECK: @GlobalS = internal constant %struct.S { i32 42, double 3.140000e+00, ptr null, i32 0 }, align 8
;.
define i32 @testOneFieldGlobalS(i32 %cmpx) {
-; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(none)
+; CHECK: Function Attrs: mustprogress norecurse nounwind willreturn memory(none)
; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS
; CHECK-SAME: (i32 [[CMPX:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: entry:
@@ -208,7 +208,7 @@ if.end7: ; preds = %if.then5, %if.end4
}
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree norecurse nosync nounwind willreturn memory(none) }
-; CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nounwind willreturn memory(none) }
+; CHECK: attributes #[[ATTR1]] = { mustprogress norecurse nounwind willreturn memory(none) }
; CHECK: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
;.
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
index 8cd1acabb4d7b..7e8c304512772 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
@@ -1528,8 +1528,8 @@ define i32 @local_alloca_not_simplifiable_1() {
; TUNIT-NEXT: [[ENTRY:.*:]]
; TUNIT-NEXT: [[X:%.*]] = alloca i32, align 4
; TUNIT-NEXT: [[Y:%.*]] = alloca i32, align 4
-; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR17]]
-; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR17]]
+; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR19:[0-9]+]]
+; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR19]]
; TUNIT-NEXT: store i32 1, ptr [[Y]], align 4, !tbaa [[INT_TBAA3]]
; TUNIT-NEXT: store i32 1, ptr [[X]], align 4, !tbaa [[INT_TBAA3]]
; TUNIT-NEXT: call void @escape(ptr noundef nonnull align 4 dereferenceable(4) [[X]])
@@ -1548,8 +1548,8 @@ define i32 @local_alloca_not_simplifiable_1() {
; CGSCC-NEXT: [[ENTRY:.*:]]
; CGSCC-NEXT: [[X:%.*]] = alloca i32, align 4
; CGSCC-NEXT: [[Y:%.*]] = alloca i32, align 4
-; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR20]]
-; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR20]]
+; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR22:[0-9]+]]
+; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR22]]
; CGSCC-NEXT: store i32 1, ptr [[Y]], align 4, !tbaa [[INT_TBAA3]]
; CGSCC-NEXT: store i32 1, ptr [[X]], align 4, !tbaa [[INT_TBAA3]]
; CGSCC-NEXT: call void @escape(ptr noundef nonnull align 4 dereferenceable(4) [[X]])
@@ -1810,7 +1810,7 @@ define i32 @static_global_not_simplifiable_2(i32 %cnd) {
; TUNIT-SAME: i32 [[CND:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
; TUNIT-NEXT: store i32 1, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
-; TUNIT-NEXT: call void @sync() #[[ATTR19:[0-9]+]]
+; TUNIT-NEXT: call void @sync() #[[ATTR20:[0-9]+]]
; TUNIT-NEXT: [[I:%.*]] = load i32, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
; TUNIT-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
; TUNIT-NEXT: ret i32 [[I]]
@@ -1819,7 +1819,7 @@ define i32 @static_global_not_simplifiable_2(i32 %cnd) {
; CGSCC-SAME: i32 [[CND:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
; CGSCC-NEXT: store i32 1, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
-; CGSCC-NEXT: call void @sync() #[[ATTR22:[0-9]+]]
+; CGSCC-NEXT: call void @sync() #[[ATTR23:[0-9]+]]
; CGSCC-NEXT: [[I:%.*]] = load i32, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
; CGSCC-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
; CGSCC-NEXT: ret i32 [[I]]
@@ -2521,14 +2521,14 @@ define dso_local ptr @malloc_like(i32 %s) {
; TUNIT-SAME: i32 [[S:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
; TUNIT-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64
-; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR20:[0-9]+]]
+; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR21:[0-9]+]]
; TUNIT-NEXT: ret ptr [[CALL]]
;
; CGSCC-LABEL: define dso_local noalias ptr @malloc_like(
; CGSCC-SAME: i32 [[S:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
; CGSCC-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64
-; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR23:[0-9]+]]
+; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR24:[0-9]+]]
; CGSCC-NEXT: ret ptr [[CALL]]
;
entry:
@@ -2541,19 +2541,19 @@ define dso_local i32 @round_trip_malloc_like(i32 %x) {
; TUNIT-LABEL: define dso_local i32 @round_trip_malloc_like(
; TUNIT-SAME: i32 [[X:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
-; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR20]]
+; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR21]]
; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]]
+; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR21]]
; TUNIT-NEXT: ret i32 [[TMP0]]
;
; CGSCC-LABEL: define dso_local i32 @round_trip_malloc_like(
; CGSCC-SAME: i32 [[X:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
-; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR23]]
+; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR24]]
; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]]
+; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24]]
; CGSCC-NEXT: ret i32 [[TMP0]]
;
entry:
@@ -2568,19 +2568,19 @@ define dso_local i32 @round_trip_unknown_alloc(i32 %x) {
; TUNIT-LABEL: define dso_local i32 @round_trip_unknown_alloc(
; TUNIT-SAME: i32 [[X:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
-; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR20]]
+; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR21]]
; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]]
+; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR21]]
; TUNIT-NEXT: ret i32 [[TMP0]]
;
; CGSCC-LABEL: define dso_local i32 @round_trip_unknown_alloc(
; CGSCC-SAME: i32 [[X:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
-; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR23]]
+; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR24]]
; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]]
+; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24]]
; CGSCC-NEXT: ret i32 [[TMP0]]
;
entry:
@@ -2597,7 +2597,7 @@ define dso_local i32 @conditional_unknown_alloc(i32 %x) {
; TUNIT-LABEL: define dso_local i32 @conditional_unknown_alloc(
; TUNIT-SAME: i32 [[X:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
-; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR20]]
+; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR21]]
; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
; TUNIT-NEXT: br i1 [[TOBOOL]], label %[[IF_END:.*]], label %[[IF_THEN:.*]]
; TUNIT: [[IF_THEN]]:
@@ -2605,13 +2605,13 @@ define dso_local i32 @conditional_unknown_alloc(i32 %x) {
; TUNIT-NEXT: br label %[[IF_END]]
; TUNIT: [[IF_END]]:
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; TUNIT-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]]
+; TUNIT-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR21]]
; TUNIT-NEXT: ret i32 [[TMP0]]
;
; CGSCC-LABEL: define dso_local i32 @conditional_unknown_alloc(
; CGSCC-SAME: i32 [[X:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
-; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR23]]
+; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR24]]
; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
; CGSCC-NEXT: br i1 [[TOBOOL]], label %[[IF_END:.*]], label %[[IF_THEN:.*]]
; CGSCC: [[IF_THEN]]:
@@ -2619,7 +2619,7 @@ define dso_local i32 @conditional_unknown_alloc(i32 %x) {
; CGSCC-NEXT: br label %[[IF_END]]
; CGSCC: [[IF_END]]:
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; CGSCC-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]]
+; CGSCC-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24]]
; CGSCC-NEXT: ret i32 [[TMP0]]
;
entry:
@@ -2659,7 +2659,7 @@ define dso_local void @test_nested_memory(ptr %dst, ptr %src) {
; TUNIT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[LOCAL_B8]], align 8
; TUNIT-NEXT: [[LOCAL_B16:%.*]] = getelementptr i8, ptr [[LOCAL]], i64 16
; TUNIT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[LOCAL_B16]], align 8
-; TUNIT-NEXT: call fastcc void @nested_memory_callee(ptr [[TMP0]], ptr [[TMP1]], ptr [[TMP2]]) #[[ATTR21:[0-9]+]]
+; TUNIT-NEXT: call fastcc void @nested_memory_callee(ptr [[TMP0]], ptr [[TMP1]], ptr [[TMP2]]) #[[ATTR22:[0-9]+]]
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define dso_local void @test_nested_memory(
@@ -2672,7 +2672,7 @@ define dso_local void @test_nested_memory(ptr %dst, ptr %src) {
; CGSCC-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
; CGSCC-NEXT: store ptr [[SRC]], ptr [[SRC2]], align 8
; CGSCC-NEXT: store ptr [[CALL]], ptr getelementptr inbounds ([[STRUCT_STY]], ptr @global, i64 0, i32 2), align 8
-; CGSCC-NEXT: call fastcc void @nested_memory_callee(ptr nofree align 4294967296 undef, ptr nofree align 4294967296 undef, ptr nofree noundef nonnull align 8 dereferenceable(24) @global) #[[ATTR24:[0-9]+]]
+; CGSCC-NEXT: call fastcc void @nested_memory_callee(ptr nofree align 4294967296 undef, ptr nofree align 4294967296 undef, ptr nofree noundef nonnull align 8 dereferenceable(24) @global) #[[ATTR25:[0-9]+]]
; CGSCC-NEXT: ret void
;
entry:
@@ -2933,7 +2933,7 @@ define i1 @alloca_non_unique_caller(i32 %in, i1 %c) {
; CGSCC: Function Attrs: nofree nosync nounwind memory(none)
; CGSCC-LABEL: define i1 @alloca_non_unique_caller(
; CGSCC-SAME: i32 [[IN:%.*]], i1 noundef [[C:%.*]]) #[[ATTR15:[0-9]+]] {
-; CGSCC-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr nofree undef, i32 [[IN]], i1 noundef [[C]]) #[[ATTR25:[0-9]+]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr nofree undef, i32 [[IN]], i1 noundef [[C]]) #[[ATTR26:[0-9]+]]
; CGSCC-NEXT: ret i1 [[R]]
;
%r = call i1 @alloca_non_unique(ptr undef, i32 %in, i1 %c)
@@ -2947,7 +2947,7 @@ define i32 @scope_value_traversal(i32 %bad, i1 %c, i1 %c2) {
; TUNIT-SAME: i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR4]] {
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
; TUNIT-NEXT: store i32 [[BAD]], ptr [[A]], align 4
-; TUNIT-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR22:[0-9]+]]
+; TUNIT-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR23:[0-9]+]]
; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4
; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]]
; TUNIT-NEXT: ret i32 [[SEL]]
@@ -2957,7 +2957,7 @@ define i32 @scope_value_traversal(i32 %bad, i1 %c, i1 %c2) {
; CGSCC-SAME: i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR16:[0-9]+]] {
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
; CGSCC-NEXT: store i32 [[BAD]], ptr [[A]], align 4
-; CGSCC-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR26:[0-9]+]]
+; CGSCC-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR27:[0-9]+]]
; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4
; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]]
; CGSCC-NEXT: ret i32 [[SEL]]
@@ -3145,8 +3145,8 @@ define i32 @recSimplify(i32 %v, i1 %cond) {
; CGSCC-NEXT: store i32 1, ptr @GRS2, align 4
; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @GRS, align 4
; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR27:[0-9]+]]
-; CGSCC-NEXT: [[R:%.*]] = call i32 @recSimplify2() #[[ATTR27]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR28:[0-9]+]]
+; CGSCC-NEXT: [[R:%.*]] = call i32 @recSimplify2() #[[ATTR28]]
; CGSCC-NEXT: ret i32 [[R]]
;
br i1 %cond, label %rec, label %comp
@@ -3245,8 +3245,8 @@ define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c
; TUNIT-NEXT: [[ENTRY:.*:]]
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
-; TUNIT-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]]) #[[ATTR23:[0-9]+]]
-; TUNIT-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
+; TUNIT-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]]) #[[ATTR24:[0-9]+]]
+; TUNIT-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR24]]
; TUNIT-NEXT: call void @write_both(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL1]]) #[[ATTR18]]
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
@@ -3259,8 +3259,8 @@ define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c
; CGSCC-NEXT: [[ENTRY:.*:]]
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
-; CGSCC-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]]) #[[ATTR28:[0-9]+]]
-; CGSCC-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]]) #[[ATTR28]]
+; CGSCC-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]]) #[[ATTR29:[0-9]+]]
+; CGSCC-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]]) #[[ATTR29]]
; CGSCC-NEXT: call void @write_both(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL1]]) #[[ATTR21]]
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
@@ -3450,9 +3450,9 @@ declare void @use3i8(i8, i8, i8)
define void @returnedPtrAccesses() {
; TUNIT-LABEL: define void @returnedPtrAccesses() {
; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8
-; TUNIT-NEXT: [[A2:%.*]] = call ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
-; TUNIT-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
-; TUNIT-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree readnone "no-capture-maybe-returned" [[A2]]) #[[ATTR23]]
+; TUNIT-NEXT: [[A2:%.*]] = call ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR25:[0-9]+]]
+; TUNIT-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR25]]
+; TUNIT-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree readnone "no-capture-maybe-returned" [[A2]]) #[[ATTR25]]
; TUNIT-NEXT: store i8 2, ptr [[A2]], align 1
; TUNIT-NEXT: store i8 4, ptr [[A4]], align 1
; TUNIT-NEXT: store i8 6, ptr [[A6]], align 1
@@ -3461,9 +3461,9 @@ define void @returnedPtrAccesses() {
;
; CGSCC-LABEL: define void @returnedPtrAccesses() {
; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8
-; CGSCC-NEXT: [[A2:%.*]] = call nonnull dereferenceable(1) ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]]
-; CGSCC-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]]
-; CGSCC-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone dereferenceable(1) [[A2]]) #[[ATTR20]]
+; CGSCC-NEXT: [[A2:%.*]] = call nonnull dereferenceable(1) ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR22]]
+; CGSCC-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR22]]
+; CGSCC-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone dereferenceable(1) [[A2]]) #[[ATTR22]]
; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2
; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4
; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6
@@ -3497,7 +3497,7 @@ define void @returnedPtrAccessesMultiple(i32 %i) {
; TUNIT-LABEL: define void @returnedPtrAccessesMultiple(
; TUNIT-SAME: i32 [[I:%.*]]) {
; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8
-; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
+; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR25]]
; TUNIT-NEXT: store i8 2, ptr [[AP]], align 1
; TUNIT-NEXT: call void @use3i8(i8 2, i8 2, i8 2)
; TUNIT-NEXT: ret void
@@ -3505,7 +3505,7 @@ define void @returnedPtrAccessesMultiple(i32 %i) {
; CGSCC-LABEL: define void @returnedPtrAccessesMultiple(
; CGSCC-SAME: i32 [[I:%.*]]) {
; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8
-; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]]
+; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR22]]
; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2
; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4
; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6
@@ -3539,7 +3539,7 @@ define void @returnedPtrAccessesMultiple2(i32 %i) {
; TUNIT-NEXT: store i8 0, ptr [[G2]], align 2
; TUNIT-NEXT: store i8 0, ptr [[G4]], align 4
; TUNIT-NEXT: store i8 0, ptr [[G6]], align 2
-; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
+; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR25]]
; TUNIT-NEXT: store i8 2, ptr [[AP]], align 1
; TUNIT-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2
; TUNIT-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4
@@ -3556,7 +3556,7 @@ define void @returnedPtrAccessesMultiple2(i32 %i) {
; CGSCC-NEXT: store i8 0, ptr [[G2]], align 2
; CGSCC-NEXT: store i8 0, ptr [[G4]], align 4
; CGSCC-NEXT: store i8 0, ptr [[G6]], align 2
-; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]]
+; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR22]]
; CGSCC-NEXT: store i8 2, ptr [[AP]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2
; CGSCC-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4
@@ -3638,11 +3638,13 @@ declare void @llvm.assume(i1 noundef)
; TUNIT: attributes #[[ATTR16:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }
; TUNIT: attributes #[[ATTR17]] = { nofree willreturn }
; TUNIT: attributes #[[ATTR18]] = { nofree nosync nounwind willreturn memory(write) }
-; TUNIT: attributes #[[ATTR19]] = { nocallback }
-; TUNIT: attributes #[[ATTR20]] = { norecurse }
-; TUNIT: attributes #[[ATTR21]] = { nounwind }
-; TUNIT: attributes #[[ATTR22]] = { nofree nosync nounwind willreturn }
-; TUNIT: attributes #[[ATTR23]] = { nofree nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR19]] = { willreturn }
+; TUNIT: attributes #[[ATTR20]] = { nocallback }
+; TUNIT: attributes #[[ATTR21]] = { norecurse }
+; TUNIT: attributes #[[ATTR22]] = { nounwind }
+; TUNIT: attributes #[[ATTR23]] = { nofree nosync nounwind willreturn }
+; TUNIT: attributes #[[ATTR24]] = { nofree nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR25]] = { nosync nounwind willreturn memory(none) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) }
@@ -3666,13 +3668,14 @@ declare void @llvm.assume(i1 noundef)
; CGSCC: attributes #[[ATTR19:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }
; CGSCC: attributes #[[ATTR20]] = { nofree willreturn }
; CGSCC: attributes #[[ATTR21]] = { nofree nounwind willreturn memory(write) }
-; CGSCC: attributes #[[ATTR22]] = { nocallback }
-; CGSCC: attributes #[[ATTR23]] = { norecurse }
-; CGSCC: attributes #[[ATTR24]] = { nounwind }
-; CGSCC: attributes #[[ATTR25]] = { nofree nounwind }
-; CGSCC: attributes #[[ATTR26]] = { nofree nounwind willreturn }
-; CGSCC: attributes #[[ATTR27]] = { nofree }
-; CGSCC: attributes #[[ATTR28]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR22]] = { willreturn }
+; CGSCC: attributes #[[ATTR23]] = { nocallback }
+; CGSCC: attributes #[[ATTR24]] = { norecurse }
+; CGSCC: attributes #[[ATTR25]] = { nounwind }
+; CGSCC: attributes #[[ATTR26]] = { nofree nounwind }
+; CGSCC: attributes #[[ATTR27]] = { nofree nounwind willreturn }
+; CGSCC: attributes #[[ATTR28]] = { nofree }
+; CGSCC: attributes #[[ATTR29]] = { nofree nosync willreturn }
;.
; TUNIT: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; TUNIT: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1}
diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll
index e3ffa99197b7d..e1361a83e74e2 100644
--- a/llvm/test/Transforms/Attributor/value-simplify.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify.ll
@@ -508,8 +508,8 @@ define ptr @complicated_args_preallocated() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
; CGSCC-LABEL: define {{[^@]+}}@complicated_args_preallocated
; CGSCC-SAME: () #[[ATTR4:[0-9]+]] {
-; CGSCC-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR13]]
-; CGSCC-NEXT: [[CALL:%.*]] = call ptr @test_preallocated(ptr nofree noundef writeonly preallocated(i32) null) #[[ATTR14:[0-9]+]] [ "preallocated"(token [[C]]) ]
+; CGSCC-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR14:[0-9]+]]
+; CGSCC-NEXT: [[CALL:%.*]] = call ptr @test_preallocated(ptr nofree noundef writeonly preallocated(i32) null) #[[ATTR15:[0-9]+]] [ "preallocated"(token [[C]]) ]
; CGSCC-NEXT: unreachable
;
%c = call token @llvm.call.preallocated.setup(i32 1)
@@ -547,7 +547,7 @@ define void @complicated_args_sret(ptr %b) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: write)
; CGSCC-LABEL: define {{[^@]+}}@complicated_args_sret
; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR6:[0-9]+]] {
-; CGSCC-NEXT: call void @test_sret(ptr nofree noundef writeonly sret([[STRUCT_X:%.*]]) dereferenceable_or_null(8) null, ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B]]) #[[ATTR15:[0-9]+]]
+; CGSCC-NEXT: call void @test_sret(ptr nofree noundef writeonly sret([[STRUCT_X:%.*]]) dereferenceable_or_null(8) null, ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B]]) #[[ATTR16:[0-9]+]]
; CGSCC-NEXT: ret void
;
call void @test_sret(ptr sret(%struct.X) null, ptr %b)
@@ -611,7 +611,7 @@ define void @complicated_args_byval() {
; CGSCC-LABEL: define {{[^@]+}}@complicated_args_byval
; CGSCC-SAME: () #[[ATTR4]] {
; CGSCC-NEXT: [[TMP1:%.*]] = load ptr, ptr @S, align 8
-; CGSCC-NEXT: call void @test_byval(ptr nofree writeonly [[TMP1]]) #[[ATTR15]]
+; CGSCC-NEXT: call void @test_byval(ptr nofree writeonly [[TMP1]]) #[[ATTR16]]
; CGSCC-NEXT: ret void
;
call void @test_byval(ptr byval(%struct.X) @S)
@@ -1281,7 +1281,7 @@ define internal i8 @memcpy_uses_store(i8 %arg) {
; CGSCC-NEXT: [[SRC:%.*]] = alloca i8, align 1
; CGSCC-NEXT: [[DST:%.*]] = alloca i8, align 1
; CGSCC-NEXT: store i8 [[ARG]], ptr [[SRC]], align 1
-; CGSCC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[DST]], ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR16:[0-9]+]]
+; CGSCC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[DST]], ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR17:[0-9]+]]
; CGSCC-NEXT: [[L:%.*]] = load i8, ptr [[DST]], align 1
; CGSCC-NEXT: ret i8 [[L]]
;
@@ -1329,10 +1329,10 @@ define i32 @test_speculatable_expr() norecurse {
; CGSCC-LABEL: define {{[^@]+}}@test_speculatable_expr
; CGSCC-SAME: () #[[ATTR9:[0-9]+]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i32, align 4
-; CGSCC-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() #[[ATTR17:[0-9]+]]
+; CGSCC-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() #[[ATTR18:[0-9]+]]
; CGSCC-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1
; CGSCC-NEXT: store i32 [[PLUS1]], ptr [[STACK]], align 4
-; CGSCC-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[PLUS1]]) #[[ATTR17]]
+; CGSCC-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[PLUS1]]) #[[ATTR18]]
; CGSCC-NEXT: ret i32 [[RSPEC]]
;
%stack = alloca i32
@@ -1457,7 +1457,7 @@ define internal void @broker(ptr %ptr) {
; CGSCC-LABEL: define {{[^@]+}}@broker
; CGSCC-SAME: () #[[ATTR2]] {
; CGSCC-NEXT: entry:
-; CGSCC-NEXT: call void @indirect() #[[ATTR18:[0-9]+]]
+; CGSCC-NEXT: call void @indirect() #[[ATTR19:[0-9]+]]
; CGSCC-NEXT: call void @unknown()
; CGSCC-NEXT: ret void
;
@@ -1702,12 +1702,13 @@ define i32 @readExtInitZeroInit() {
; CGSCC: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
; CGSCC: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR12]] = { nofree nosync willreturn }
-; CGSCC: attributes #[[ATTR13]] = { nofree willreturn }
-; CGSCC: attributes #[[ATTR14]] = { nofree nounwind willreturn }
-; CGSCC: attributes #[[ATTR15]] = { nofree nounwind willreturn memory(write) }
-; CGSCC: attributes #[[ATTR16]] = { nofree willreturn memory(readwrite) }
-; CGSCC: attributes #[[ATTR17]] = { nosync }
-; CGSCC: attributes #[[ATTR18]] = { nounwind }
+; CGSCC: attributes #[[ATTR13]] = { willreturn }
+; CGSCC: attributes #[[ATTR14]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR15]] = { nofree nounwind willreturn }
+; CGSCC: attributes #[[ATTR16]] = { nofree nounwind willreturn memory(write) }
+; CGSCC: attributes #[[ATTR17]] = { nofree willreturn memory(readwrite) }
+; CGSCC: attributes #[[ATTR18]] = { nosync }
+; CGSCC: attributes #[[ATTR19]] = { nounwind }
;.
; TUNIT: [[META0]] = !{}
;.
diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
index 53b3be2218db3..7e9a93cb186ed 100644
--- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -652,7 +652,7 @@ define void @test_cmpxchg(ptr %p) {
; FNATTRS-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], i32 0, i32 1 acquire monotonic, align 4
; FNATTRS-NEXT: ret void
;
-; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; ATTRIBUTOR: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; ATTRIBUTOR-LABEL: define void @test_cmpxchg
; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[P:%.*]]) #[[ATTR11:[0-9]+]] {
; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], i32 0, i32 1 acquire monotonic, align 4
@@ -669,9 +669,9 @@ define void @test_cmpxchg_ptr(ptr %p, ptr %q) {
; FNATTRS-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], ptr null, ptr [[Q]] acquire monotonic, align 8
; FNATTRS-NEXT: ret void
;
-; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; ATTRIBUTOR: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; ATTRIBUTOR-LABEL: define void @test_cmpxchg_ptr
-; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[P:%.*]], ptr nofree [[Q:%.*]]) #[[ATTR11]] {
+; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR11]] {
; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = cmpxchg ptr [[P]], ptr null, ptr [[Q]] acquire monotonic, align 8
; ATTRIBUTOR-NEXT: ret void
;
@@ -686,7 +686,7 @@ define void @test_atomicrmw(ptr %p) {
; FNATTRS-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i32 1 seq_cst, align 4
; FNATTRS-NEXT: ret void
;
-; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; ATTRIBUTOR: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; ATTRIBUTOR-LABEL: define void @test_atomicrmw
; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[P:%.*]]) #[[ATTR11]] {
; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i32 1 seq_cst, align 4
diff --git a/llvm/test/Transforms/FunctionAttrs/nonnull.ll b/llvm/test/Transforms/FunctionAttrs/nonnull.ll
index 9441db4b80c81..869c85e60a8e6 100644
--- a/llvm/test/Transforms/FunctionAttrs/nonnull.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nonnull.ll
@@ -274,7 +274,7 @@ define ptr @test11(ptr) local_unnamed_addr {
; FNATTRS-NEXT: ret ptr [[TMP6]]
;
; ATTRIBUTOR-LABEL: define nonnull ptr @test11(
-; ATTRIBUTOR-SAME: ptr [[TMP0:%.*]]) local_unnamed_addr {
+; ATTRIBUTOR-SAME: ptr nofree [[TMP0:%.*]]) local_unnamed_addr {
; ATTRIBUTOR-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null
; ATTRIBUTOR-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
; ATTRIBUTOR: 3:
@@ -855,17 +855,11 @@ f:
; The volatile load can trap, so we can't guarantee that we'll get to the call.
define i8 @parent6(ptr %a, ptr %b) {
-; FNATTRS-LABEL: define i8 @parent6(
-; FNATTRS-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) {
-; FNATTRS-NEXT: [[C:%.*]] = load volatile i8, ptr [[B]], align 1
-; FNATTRS-NEXT: call void @use1nonnull(ptr [[A]])
-; FNATTRS-NEXT: ret i8 [[C]]
-;
-; ATTRIBUTOR-LABEL: define i8 @parent6(
-; ATTRIBUTOR-SAME: ptr [[A:%.*]], ptr nofree [[B:%.*]]) {
-; ATTRIBUTOR-NEXT: [[C:%.*]] = load volatile i8, ptr [[B]], align 1
-; ATTRIBUTOR-NEXT: call void @use1nonnull(ptr [[A]])
-; ATTRIBUTOR-NEXT: ret i8 [[C]]
+; COMMON-LABEL: define i8 @parent6(
+; COMMON-SAME: ptr [[A:%.*]], ptr [[B:%.*]]) {
+; COMMON-NEXT: [[C:%.*]] = load volatile i8, ptr [[B]], align 1
+; COMMON-NEXT: call void @use1nonnull(ptr [[A]])
+; COMMON-NEXT: ret i8 [[C]]
;
%c = load volatile i8, ptr %b
diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll
index 264f6efb9530a..9704829fd4415 100644
--- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -385,7 +385,7 @@ define void @unsound_readnone(ptr %ignored, ptr %escaped_then_written) {
; FNATTRS-NEXT: ret void
;
; ATTRIBUTOR-LABEL: define {{[^@]+}}@unsound_readnone
-; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
+; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr [[ESCAPED_THEN_WRITTEN:%.*]]) {
; ATTRIBUTOR-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
; ATTRIBUTOR-NEXT: call void @escape_readnone_ptr(ptr [[ADDR]], ptr nofree [[ESCAPED_THEN_WRITTEN]])
; ATTRIBUTOR-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
@@ -393,7 +393,7 @@ define void @unsound_readnone(ptr %ignored, ptr %escaped_then_written) {
; ATTRIBUTOR-NEXT: ret void
;
; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@unsound_readnone
-; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
+; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr [[ESCAPED_THEN_WRITTEN:%.*]]) {
; ATTRIBUTOR-CGSCC-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
; ATTRIBUTOR-CGSCC-NEXT: call void @escape_readnone_ptr(ptr [[ADDR]], ptr nofree [[ESCAPED_THEN_WRITTEN]])
; ATTRIBUTOR-CGSCC-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
@@ -417,7 +417,7 @@ define void @unsound_readonly(ptr %ignored, ptr %escaped_then_written) {
; FNATTRS-NEXT: ret void
;
; ATTRIBUTOR-LABEL: define {{[^@]+}}@unsound_readonly
-; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
+; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr [[ESCAPED_THEN_WRITTEN:%.*]]) {
; ATTRIBUTOR-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
; ATTRIBUTOR-NEXT: call void @escape_readonly_ptr(ptr [[ADDR]], ptr nofree [[ESCAPED_THEN_WRITTEN]])
; ATTRIBUTOR-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
@@ -425,7 +425,7 @@ define void @unsound_readonly(ptr %ignored, ptr %escaped_then_written) {
; ATTRIBUTOR-NEXT: ret void
;
; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@unsound_readonly
-; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr nofree [[ESCAPED_THEN_WRITTEN:%.*]]) {
+; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readnone captures(none) [[IGNORED:%.*]], ptr [[ESCAPED_THEN_WRITTEN:%.*]]) {
; ATTRIBUTOR-CGSCC-NEXT: [[ADDR:%.*]] = alloca ptr, align 8
; ATTRIBUTOR-CGSCC-NEXT: call void @escape_readonly_ptr(ptr [[ADDR]], ptr nofree [[ESCAPED_THEN_WRITTEN]])
; ATTRIBUTOR-CGSCC-NEXT: [[ADDR_LD:%.*]] = load ptr, ptr [[ADDR]], align 8
@@ -467,12 +467,12 @@ define void @fptr_test1b(ptr %p, ptr %f) {
; FNATTRS-NEXT: ret void
;
; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test1b
-; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]], ptr nofree nonnull captures(none) [[F:%.*]]) {
+; ATTRIBUTOR-SAME: (ptr [[P:%.*]], ptr nofree nonnull captures(none) [[F:%.*]]) {
; ATTRIBUTOR-NEXT: call void [[F]](ptr nofree readnone [[P]])
; ATTRIBUTOR-NEXT: ret void
;
; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test1b
-; ATTRIBUTOR-CGSCC-SAME: (ptr nofree [[P:%.*]], ptr nofree nonnull captures(none) [[F:%.*]]) {
+; ATTRIBUTOR-CGSCC-SAME: (ptr [[P:%.*]], ptr nofree nonnull captures(none) [[F:%.*]]) {
; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nofree readnone [[P]])
; ATTRIBUTOR-CGSCC-NEXT: ret void
;
@@ -489,13 +489,13 @@ define void @fptr_test1c(ptr %p, ptr %f) {
;
; ATTRIBUTOR: Function Attrs: memory(read)
; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test1c
-; ATTRIBUTOR-SAME: (ptr nofree readonly [[P:%.*]], ptr nofree nonnull readonly captures(none) [[F:%.*]]) #[[ATTR2:[0-9]+]] {
+; ATTRIBUTOR-SAME: (ptr readonly [[P:%.*]], ptr nofree nonnull readonly captures(none) [[F:%.*]]) #[[ATTR2:[0-9]+]] {
; ATTRIBUTOR-NEXT: call void [[F]](ptr nofree readnone [[P]]) #[[ATTR2]]
; ATTRIBUTOR-NEXT: ret void
;
; ATTRIBUTOR-CGSCC: Function Attrs: memory(read)
; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test1c
-; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readonly [[P:%.*]], ptr nofree nonnull readonly captures(none) [[F:%.*]]) #[[ATTR2:[0-9]+]] {
+; ATTRIBUTOR-CGSCC-SAME: (ptr readonly [[P:%.*]], ptr nofree nonnull readonly captures(none) [[F:%.*]]) #[[ATTR2:[0-9]+]] {
; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nofree readnone [[P]]) #[[ATTR2]]
; ATTRIBUTOR-CGSCC-NEXT: ret void
;
@@ -531,12 +531,12 @@ define void @fptr_test2b(ptr %p, ptr %f) {
; FNATTRS-NEXT: ret void
;
; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test2b
-; ATTRIBUTOR-SAME: (ptr nofree [[P:%.*]], ptr nofree nonnull captures(none) [[F:%.*]]) {
+; ATTRIBUTOR-SAME: (ptr [[P:%.*]], ptr nofree nonnull captures(none) [[F:%.*]]) {
; ATTRIBUTOR-NEXT: call void [[F]](ptr nofree readonly [[P]])
; ATTRIBUTOR-NEXT: ret void
;
; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test2b
-; ATTRIBUTOR-CGSCC-SAME: (ptr nofree [[P:%.*]], ptr nofree nonnull captures(none) [[F:%.*]]) {
+; ATTRIBUTOR-CGSCC-SAME: (ptr [[P:%.*]], ptr nofree nonnull captures(none) [[F:%.*]]) {
; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nofree readonly [[P]])
; ATTRIBUTOR-CGSCC-NEXT: ret void
;
@@ -553,13 +553,13 @@ define void @fptr_test2c(ptr %p, ptr %f) {
;
; ATTRIBUTOR: Function Attrs: memory(read)
; ATTRIBUTOR-LABEL: define {{[^@]+}}@fptr_test2c
-; ATTRIBUTOR-SAME: (ptr nofree readonly [[P:%.*]], ptr nofree nonnull readonly captures(none) [[F:%.*]]) #[[ATTR2]] {
+; ATTRIBUTOR-SAME: (ptr readonly [[P:%.*]], ptr nofree nonnull readonly captures(none) [[F:%.*]]) #[[ATTR2]] {
; ATTRIBUTOR-NEXT: call void [[F]](ptr nofree readonly [[P]]) #[[ATTR2]]
; ATTRIBUTOR-NEXT: ret void
;
; ATTRIBUTOR-CGSCC: Function Attrs: memory(read)
; ATTRIBUTOR-CGSCC-LABEL: define {{[^@]+}}@fptr_test2c
-; ATTRIBUTOR-CGSCC-SAME: (ptr nofree readonly [[P:%.*]], ptr nofree nonnull readonly captures(none) [[F:%.*]]) #[[ATTR2]] {
+; ATTRIBUTOR-CGSCC-SAME: (ptr readonly [[P:%.*]], ptr nofree nonnull readonly captures(none) [[F:%.*]]) #[[ATTR2]] {
; ATTRIBUTOR-CGSCC-NEXT: call void [[F]](ptr nofree readonly [[P]]) #[[ATTR2]]
; ATTRIBUTOR-CGSCC-NEXT: ret void
;
diff --git a/llvm/test/Transforms/FunctionAttrs/writeonly.ll b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
index 8e8ade356aae3..325bc53d2615b 100644
--- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll
+++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
@@ -168,7 +168,7 @@ define void @test_atomicrmw(ptr %p) {
; FNATTRS-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1
; FNATTRS-NEXT: ret void
;
-; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
+; ATTRIBUTOR: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite)
; ATTRIBUTOR-LABEL: define {{[^@]+}}@test_atomicrmw
; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[P:%.*]]) #[[ATTR7:[0-9]+]] {
; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1
diff --git a/llvm/test/Transforms/OpenMP/parallel_deletion.ll b/llvm/test/Transforms/OpenMP/parallel_deletion.ll
index 0b6c4f32772f5..bb6b0379a0952 100644
--- a/llvm/test/Transforms/OpenMP/parallel_deletion.ll
+++ b/llvm/test/Transforms/OpenMP/parallel_deletion.ll
@@ -282,12 +282,12 @@ define void @delete_parallel_2() {
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR18:[0-9]+]]
+; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR15]]
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..3, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]])
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..4, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]])
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..5, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]])
-; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..6, ptr noundef nonnull align 4 captures(none) dereferenceable(4) [[A]])
+; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..6, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]])
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr noundef nonnull [[A]])
; CHECK-NEXT: ret void
;
@@ -329,7 +329,7 @@ define internal void @.omp_outlined..3(ptr noalias %.global_tid., ptr noalias %.
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3
; CHECK-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR19:[0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR18:[0-9]+]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
@@ -457,7 +457,7 @@ define internal void @.omp_outlined..5(ptr noalias %.global_tid., ptr noalias %.
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
; CHECK-SAME: (ptr noalias nofree readonly captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR19]]
+; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR19:[0-9]+]]
; CHECK-NEXT: [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4, !invariant.load [[META1]]
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
@@ -527,7 +527,7 @@ omp_if.end: ; preds = %entry, %omp_if.then
define internal void @.omp_outlined..6(ptr noalias %.global_tid., ptr noalias %.bound_tid., ptr dereferenceable(4) %a) {
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
-; CHECK-SAME: (ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
+; CHECK-SAME: (ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A1:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x ptr], align 8
>From 34b5b72f825309b820c1c98f882d8b30ff7b592c Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 15 May 2026 10:15:38 +0200
Subject: [PATCH 3/4] Make function nofree inference in Attributor more precise
---
.../Transforms/IPO/AttributorAttributes.cpp | 26 ++--
.../ArgumentPromotion/X86/thiscall.ll | 4 +-
.../Attributor/dereferenceable-1.ll | 4 +-
llvm/test/Transforms/Attributor/liveness.ll | 131 ++++++++++--------
llvm/test/Transforms/Attributor/misc.ll | 4 +-
llvm/test/Transforms/Attributor/noalias.ll | 4 +-
llvm/test/Transforms/Attributor/nofree.ll | 52 +++----
llvm/test/Transforms/Attributor/nonnull.ll | 18 ++-
llvm/test/Transforms/Attributor/range.ll | 112 ++++++++-------
.../Attributor/value-simplify-assume.ll | 106 +++++++-------
.../Attributor/value-simplify-pointer-info.ll | 110 ++++++++-------
.../Transforms/OpenMP/parallel_deletion.ll | 6 +-
12 files changed, 291 insertions(+), 286 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 2f3cfe2fcc054..d9a886eaa236b 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -2281,24 +2281,22 @@ struct AANoFreeImpl : public AANoFree {
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
- // Make sure that synchronization cannot establish happens-before with a
- // free on another thread.
- const IRPosition &IRP = getIRPosition();
- bool IsKnown;
- if (!AA::hasAssumedIRAttr<Attribute::NoSync>(
- A, this, IRPosition::function_scope(IRP), DepClassTy::REQUIRED,
- IsKnown))
- return indicatePessimisticFixpoint();
-
auto CheckForNoFree = [&](Instruction &I) {
- bool IsKnown;
- return AA::hasAssumedIRAttr<Attribute::NoFree>(
- A, this, IRPosition::callsite_function(cast<CallBase>(I)),
- DepClassTy::REQUIRED, IsKnown);
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ bool IsKnown;
+ return AA::hasAssumedIRAttr<Attribute::NoFree>(
+ A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
+ IsKnown);
+ }
+ // Make sure that synchronization cannot establish happens-before with a
+ // free on another thread.
+ return AA::isNoSyncInst(A, I, *this);
};
bool UsedAssumedInformation = false;
- if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
+ if (!A.checkForAllReadWriteInstructions(CheckForNoFree, *this,
+ UsedAssumedInformation) ||
+ !A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
UsedAssumedInformation))
return indicatePessimisticFixpoint();
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
index 139f42c6d36e1..4795b424b0d2d 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
@@ -59,8 +59,8 @@ declare ptr @llvm.stacksave()
declare void @llvm.stackrestore(ptr)
;.
; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn }
-; TUNIT: attributes #[[ATTR1]] = { willreturn }
+; TUNIT: attributes #[[ATTR1]] = { nofree willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn }
-; CGSCC: attributes #[[ATTR1]] = { willreturn }
+; CGSCC: attributes #[[ATTR1]] = { nofree willreturn }
;.
diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
index 33e621c953d13..5699284128388 100644
--- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll
+++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
@@ -820,7 +820,7 @@ f:
; TUNIT: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn memory(write) }
; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind memory(write) }
-; TUNIT: attributes #[[ATTR9]] = { willreturn memory(write) }
+; TUNIT: attributes #[[ATTR9]] = { nofree willreturn memory(write) }
; TUNIT: attributes #[[ATTR10]] = { nounwind }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
@@ -832,7 +832,7 @@ f:
; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
; CGSCC: attributes #[[ATTR7]] = { nofree nounwind willreturn memory(write) }
; CGSCC: attributes #[[ATTR8]] = { nofree nosync nounwind memory(write) }
-; CGSCC: attributes #[[ATTR9]] = { willreturn memory(write) }
+; CGSCC: attributes #[[ATTR9]] = { nofree willreturn memory(write) }
; CGSCC: attributes #[[ATTR10]] = { nounwind }
;.
; TUNIT: [[RNG0]] = !{i64 10, i64 100}
diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll
index e2f3edff940e1..a83a3c5f9c6e9 100644
--- a/llvm/test/Transforms/Attributor/liveness.ll
+++ b/llvm/test/Transforms/Attributor/liveness.ll
@@ -206,20 +206,35 @@ cond.end: ; preds = %cond.false, %cond.t
; TEST 3: both cond.true and cond.false are dead, therfore cond.end is dead as well.
define i32 @all_dead(i32 %a) #0 {
-; CHECK: Function Attrs: noreturn
-; CHECK-LABEL: define {{[^@]+}}@all_dead
-; CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR4:[0-9]+]] {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
-; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-; CHECK: cond.true:
-; CHECK-NEXT: call void @no_return_call() #[[ATTR3:[0-9]+]]
-; CHECK-NEXT: unreachable
-; CHECK: cond.false:
-; CHECK-NEXT: call void @no_return_call() #[[ATTR3]]
-; CHECK-NEXT: unreachable
-; CHECK: cond.end:
-; CHECK-NEXT: unreachable
+; TUNIT: Function Attrs: noreturn
+; TUNIT-LABEL: define {{[^@]+}}@all_dead
+; TUNIT-SAME: (i32 [[A:%.*]]) #[[ATTR4:[0-9]+]] {
+; TUNIT-NEXT: entry:
+; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
+; TUNIT-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+; TUNIT: cond.true:
+; TUNIT-NEXT: call void @no_return_call() #[[ATTR16]]
+; TUNIT-NEXT: unreachable
+; TUNIT: cond.false:
+; TUNIT-NEXT: call void @no_return_call() #[[ATTR3:[0-9]+]]
+; TUNIT-NEXT: unreachable
+; TUNIT: cond.end:
+; TUNIT-NEXT: unreachable
+;
+; CGSCC: Function Attrs: noreturn
+; CGSCC-LABEL: define {{[^@]+}}@all_dead
+; CGSCC-SAME: (i32 [[A:%.*]]) #[[ATTR4:[0-9]+]] {
+; CGSCC-NEXT: entry:
+; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
+; CGSCC-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+; CGSCC: cond.true:
+; CGSCC-NEXT: call void @no_return_call() #[[ATTR18]]
+; CGSCC-NEXT: unreachable
+; CGSCC: cond.false:
+; CGSCC-NEXT: call void @no_return_call() #[[ATTR3:[0-9]+]]
+; CGSCC-NEXT: unreachable
+; CGSCC: cond.end:
+; CGSCC-NEXT: unreachable
;
entry:
%cmp = icmp eq i32 %a, 0
@@ -254,7 +269,7 @@ define i32 @all_live(i32 %a) #0 {
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
; CHECK-NEXT: call void @normal_call()
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn() #[[ATTR4]]
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn() #[[ATTR4:[0-9]+]]
; CHECK-NEXT: unreachable
; CHECK: cond.false:
; CHECK-NEXT: call void @normal_call()
@@ -345,7 +360,7 @@ define i32 @invoke_noreturn_nounwind(i32 %a) personality ptr @__gxx_personality_
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.true:
; CHECK-NEXT: call void @normal_call()
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn_nounwind() #[[ATTR3]]
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn_nounwind() #[[ATTR3:[0-9]+]]
; CHECK-NEXT: unreachable
; CHECK: cond.false:
; CHECK-NEXT: call void @normal_call()
@@ -917,28 +932,28 @@ define linkonce_odr void @non_exact1() {
define internal void @middle() {
; TUNIT-LABEL: define {{[^@]+}}@middle() {
; TUNIT-NEXT: bb0:
-; TUNIT-NEXT: call void @non_dead_b0() #[[ATTR18:[0-9]+]]
-; TUNIT-NEXT: call void @non_dead_b1() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b2() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b3() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b0() #[[ATTR11:[0-9]+]]
+; TUNIT-NEXT: call void @non_dead_b1() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b2() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b3() #[[ATTR11]]
; TUNIT-NEXT: br label [[BB1:%.*]]
; TUNIT: bb1:
-; TUNIT-NEXT: call void @non_dead_b4() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b5() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b6() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b7() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b4() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b5() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b6() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b7() #[[ATTR11]]
; TUNIT-NEXT: br label [[BB2:%.*]]
; TUNIT: bb2:
-; TUNIT-NEXT: call void @non_dead_b8() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b9() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b10() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b11() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b8() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b9() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b10() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b11() #[[ATTR11]]
; TUNIT-NEXT: br label [[BB3:%.*]]
; TUNIT: bb3:
-; TUNIT-NEXT: call void @non_dead_b12() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b13() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b14() #[[ATTR18]]
-; TUNIT-NEXT: call void @non_dead_b15() #[[ATTR18]]
+; TUNIT-NEXT: call void @non_dead_b12() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b13() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b14() #[[ATTR11]]
+; TUNIT-NEXT: call void @non_dead_b15() #[[ATTR11]]
; TUNIT-NEXT: br label [[BB4:%.*]]
; TUNIT: bb4:
; TUNIT-NEXT: call void @non_exact2()
@@ -946,28 +961,28 @@ define internal void @middle() {
;
; CGSCC-LABEL: define {{[^@]+}}@middle() {
; CGSCC-NEXT: bb0:
-; CGSCC-NEXT: call void @non_dead_b0() #[[ATTR20:[0-9]+]]
-; CGSCC-NEXT: call void @non_dead_b1() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b2() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b3() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b0() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b1() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b2() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b3() #[[ATTR19]]
; CGSCC-NEXT: br label [[BB1:%.*]]
; CGSCC: bb1:
-; CGSCC-NEXT: call void @non_dead_b4() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b5() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b6() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b7() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b4() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b5() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b6() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b7() #[[ATTR19]]
; CGSCC-NEXT: br label [[BB2:%.*]]
; CGSCC: bb2:
-; CGSCC-NEXT: call void @non_dead_b8() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b9() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b10() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b11() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b8() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b9() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b10() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b11() #[[ATTR19]]
; CGSCC-NEXT: br label [[BB3:%.*]]
; CGSCC: bb3:
-; CGSCC-NEXT: call void @non_dead_b12() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b13() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b14() #[[ATTR20]]
-; CGSCC-NEXT: call void @non_dead_b15() #[[ATTR20]]
+; CGSCC-NEXT: call void @non_dead_b12() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b13() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b14() #[[ATTR19]]
+; CGSCC-NEXT: call void @non_dead_b15() #[[ATTR19]]
; CGSCC-NEXT: br label [[BB4:%.*]]
; CGSCC: bb4:
; CGSCC-NEXT: call void @non_exact2()
@@ -2184,7 +2199,7 @@ define internal void @useless_arg_almost_sink(ptr %a) {
; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(readwrite, argmem: none)
; TUNIT-LABEL: define {{[^@]+}}@useless_arg_almost_sink
; TUNIT-SAME: () #[[ATTR13]] {
-; TUNIT-NEXT: call void @useless_arg_sink() #[[ATTR11:[0-9]+]]
+; TUNIT-NEXT: call void @useless_arg_sink() #[[ATTR11]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(readwrite, argmem: none)
@@ -2326,7 +2341,7 @@ define i32 @switch_default_dead_caller() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@switch_default_dead_caller
; CGSCC-SAME: () #[[ATTR12]] {
-; CGSCC-NEXT: [[CALL2:%.*]] = tail call noundef i32 @switch_default_dead() #[[ATTR21:[0-9]+]]
+; CGSCC-NEXT: [[CALL2:%.*]] = tail call noundef i32 @switch_default_dead() #[[ATTR20:[0-9]+]]
; CGSCC-NEXT: ret i32 [[CALL2]]
;
%call2 = tail call i32 @switch_default_dead(i64 0)
@@ -2576,7 +2591,7 @@ define void @bad_gep() {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[N1:%.*]] = alloca i8, i32 0, align 1
; TUNIT-NEXT: [[M2:%.*]] = alloca i8, i32 0, align 1
-; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR19:[0-9]+]]
+; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR18:[0-9]+]]
; TUNIT-NEXT: br label [[EXIT:%.*]]
; TUNIT: while.body:
; TUNIT-NEXT: unreachable
@@ -2585,7 +2600,7 @@ define void @bad_gep() {
; TUNIT: if.end:
; TUNIT-NEXT: unreachable
; TUNIT: exit:
-; TUNIT-NEXT: call void @llvm.lifetime.end.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR19]]
+; TUNIT-NEXT: call void @llvm.lifetime.end.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR18]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
@@ -2594,7 +2609,7 @@ define void @bad_gep() {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: [[N1:%.*]] = alloca i8, i32 0, align 1
; CGSCC-NEXT: [[M2:%.*]] = alloca i8, i32 0, align 1
-; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR22:[0-9]+]]
+; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR21:[0-9]+]]
; CGSCC-NEXT: br label [[EXIT:%.*]]
; CGSCC: while.body:
; CGSCC-NEXT: unreachable
@@ -2603,7 +2618,7 @@ define void @bad_gep() {
; CGSCC: if.end:
; CGSCC-NEXT: unreachable
; CGSCC: exit:
-; CGSCC-NEXT: call void @llvm.lifetime.end.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR22]]
+; CGSCC-NEXT: call void @llvm.lifetime.end.p0(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[N1]]) #[[ATTR21]]
; CGSCC-NEXT: ret void
;
entry:
@@ -2687,8 +2702,7 @@ declare void @llvm.lifetime.end.p0(ptr %1)
; TUNIT: attributes #[[ATTR15:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
; TUNIT: attributes #[[ATTR16]] = { nofree noreturn nounwind }
; TUNIT: attributes #[[ATTR17]] = { nofree nounwind willreturn }
-; TUNIT: attributes #[[ATTR18]] = { nosync nounwind willreturn }
-; TUNIT: attributes #[[ATTR19]] = { nofree willreturn }
+; TUNIT: attributes #[[ATTR18]] = { nofree willreturn }
;.
; CGSCC: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind }
; CGSCC: attributes #[[ATTR1:[0-9]+]] = { memory(none) }
@@ -2710,7 +2724,6 @@ declare void @llvm.lifetime.end.p0(ptr %1)
; CGSCC: attributes #[[ATTR17:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR18]] = { nofree noreturn nounwind }
; CGSCC: attributes #[[ATTR19]] = { nofree nounwind willreturn }
-; CGSCC: attributes #[[ATTR20]] = { nounwind willreturn }
-; CGSCC: attributes #[[ATTR21]] = { nofree nosync willreturn }
-; CGSCC: attributes #[[ATTR22]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR20]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR21]] = { nofree willreturn }
;.
diff --git a/llvm/test/Transforms/Attributor/misc.ll b/llvm/test/Transforms/Attributor/misc.ll
index 20ac0d65b47b8..c3458894fe84e 100644
--- a/llvm/test/Transforms/Attributor/misc.ll
+++ b/llvm/test/Transforms/Attributor/misc.ll
@@ -101,8 +101,8 @@ declare void @callback1(ptr)
declare void @callback2(ptr)
;.
; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
-; TUNIT: attributes #[[ATTR1]] = { nosync nounwind willreturn memory(write) }
+; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(write) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
-; CGSCC: attributes #[[ATTR1]] = { nounwind willreturn memory(write) }
+; CGSCC: attributes #[[ATTR1]] = { nofree nounwind willreturn memory(write) }
;.
diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll
index b989daafaedba..415958e151634 100644
--- a/llvm/test/Transforms/Attributor/noalias.ll
+++ b/llvm/test/Transforms/Attributor/noalias.ll
@@ -950,7 +950,7 @@ l2:
; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn memory(read) }
-; TUNIT: attributes #[[ATTR13]] = { willreturn memory(readwrite) }
+; TUNIT: attributes #[[ATTR13]] = { nofree willreturn memory(readwrite) }
; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn memory(write) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
@@ -967,7 +967,7 @@ l2:
; CGSCC: attributes #[[ATTR11]] = { mustprogress nofree nosync nounwind willreturn memory(write) }
; CGSCC: attributes #[[ATTR12]] = { nofree nosync willreturn }
; CGSCC: attributes #[[ATTR13]] = { nofree willreturn memory(read) }
-; CGSCC: attributes #[[ATTR14]] = { willreturn memory(readwrite) }
+; CGSCC: attributes #[[ATTR14]] = { nofree willreturn memory(readwrite) }
; CGSCC: attributes #[[ATTR15]] = { nofree nounwind willreturn memory(write) }
;.
; TUNIT: [[META0]] = !{}
diff --git a/llvm/test/Transforms/Attributor/nofree.ll b/llvm/test/Transforms/Attributor/nofree.ll
index 4a059fd1adf5f..94aa79aa327f4 100644
--- a/llvm/test/Transforms/Attributor/nofree.ll
+++ b/llvm/test/Transforms/Attributor/nofree.ll
@@ -255,7 +255,7 @@ define float @call_floor2(float %a) #0 {
; CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable
; CHECK-LABEL: define {{[^@]+}}@call_floor2
; CHECK-SAME: (float [[A:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT: [[C:%.*]] = tail call nofpclass(sub) float @llvm.floor.f32(float [[A]]) #[[ATTR13:[0-9]+]]
+; CHECK-NEXT: [[C:%.*]] = tail call nofpclass(sub) float @llvm.floor.f32(float [[A]]) #[[ATTR14:[0-9]+]]
; CHECK-NEXT: ret float [[C]]
;
%c = tail call float @llvm.floor.f32(float %a)
@@ -297,12 +297,12 @@ define void @f2() #0 {
; TEST 12 NoFree argument - positive.
define double @test12(ptr nocapture readonly %a) {
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
; CHECK-LABEL: define {{[^@]+}}@test12
-; CHECK-SAME: (ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR0]] {
+; CHECK-SAME: (ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR7:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[A]], align 8
-; CHECK-NEXT: [[CALL:%.*]] = tail call double @cos(double [[TMP0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call double @cos(double [[TMP0]]) #[[ATTR8:[0-9]+]]
; CHECK-NEXT: ret double [[CALL]]
;
entry:
@@ -352,7 +352,7 @@ define void @nonnull_assume_pos(ptr %arg1, ptr %arg2, ptr %arg3, ptr %arg4) {
;
; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_pos
; CHECK-SAME: (ptr nofree [[ARG1:%.*]], ptr [[ARG2:%.*]], ptr nofree [[ARG3:%.*]], ptr [[ARG4:%.*]]) {
-; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14:[0-9]+]] [ "nofree"(ptr [[ARG1]]), "nofree"(ptr [[ARG3]]) ]
+; CHECK-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR15:[0-9]+]] [ "nofree"(ptr [[ARG1]]), "nofree"(ptr [[ARG3]]) ]
; CHECK-NEXT: call void @unknown(ptr nofree [[ARG1]], ptr [[ARG2]], ptr nofree [[ARG3]], ptr [[ARG4]])
; CHECK-NEXT: ret void
;
@@ -426,7 +426,7 @@ define void @nonnull_assume_call(ptr %arg1, ptr %arg2, ptr %arg3, ptr %arg4) {
define weak void @implied_nofree1() readnone {
; CHECK: Function Attrs: nosync memory(none)
; CHECK-LABEL: define {{[^@]+}}@implied_nofree1
-; CHECK-SAME: () #[[ATTR8:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR9:[0-9]+]] {
; CHECK-NEXT: ret void
;
ret void
@@ -435,7 +435,7 @@ define weak void @implied_nofree1() readnone {
define weak void @implied_nofree2() readonly {
; CHECK: Function Attrs: nosync memory(read)
; CHECK-LABEL: define {{[^@]+}}@implied_nofree2
-; CHECK-SAME: () #[[ATTR9:[0-9]+]] {
+; CHECK-SAME: () #[[ATTR10:[0-9]+]] {
; CHECK-NEXT: ret void
;
ret void
@@ -458,7 +458,7 @@ define weak void @implied_nofree4(ptr readonly %a) {
define weak void @implied_nofree5(ptr %a) readonly {
; CHECK: Function Attrs: nosync memory(read)
; CHECK-LABEL: define {{[^@]+}}@implied_nofree5
-; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR9]] {
+; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR10]] {
; CHECK-NEXT: ret void
;
ret void
@@ -466,7 +466,7 @@ define weak void @implied_nofree5(ptr %a) readonly {
define weak void @implied_nofree6(ptr %a) nofree {
; CHECK: Function Attrs: nofree
; CHECK-LABEL: define {{[^@]+}}@implied_nofree6
-; CHECK-SAME: (ptr nofree [[A:%.*]]) #[[ATTR10:[0-9]+]] {
+; CHECK-SAME: (ptr nofree [[A:%.*]]) #[[ATTR11:[0-9]+]] {
; CHECK-NEXT: ret void
;
ret void
@@ -490,14 +490,15 @@ attributes #2 = { nobuiltin nounwind }
; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree noinline nosync nounwind willreturn memory(none) uwtable }
; TUNIT: attributes #[[ATTR5:[0-9]+]] = { nofree noinline nounwind memory(none) uwtable }
; TUNIT: attributes #[[ATTR6:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
-; TUNIT: attributes #[[ATTR7:[0-9]+]] = { nobuiltin nofree nounwind }
-; TUNIT: attributes #[[ATTR8]] = { nosync memory(none) }
-; TUNIT: attributes #[[ATTR9]] = { nosync memory(read) }
-; TUNIT: attributes #[[ATTR10]] = { nofree }
-; TUNIT: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
-; TUNIT: attributes #[[ATTR12:[0-9]+]] = { nounwind willreturn }
-; TUNIT: attributes #[[ATTR13]] = { nofree nosync willreturn }
-; TUNIT: attributes #[[ATTR14]] = { willreturn memory(write) }
+; TUNIT: attributes #[[ATTR7]] = { nofree nounwind }
+; TUNIT: attributes #[[ATTR8]] = { nobuiltin nofree nounwind }
+; TUNIT: attributes #[[ATTR9]] = { nosync memory(none) }
+; TUNIT: attributes #[[ATTR10]] = { nosync memory(read) }
+; TUNIT: attributes #[[ATTR11]] = { nofree }
+; TUNIT: attributes #[[ATTR12:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
+; TUNIT: attributes #[[ATTR13:[0-9]+]] = { nounwind willreturn }
+; TUNIT: attributes #[[ATTR14]] = { nofree nosync willreturn }
+; TUNIT: attributes #[[ATTR15]] = { nofree willreturn memory(write) }
;.
; CGSCC: attributes #[[ATTR0]] = { nounwind }
; CGSCC: attributes #[[ATTR1]] = { noinline nounwind uwtable }
@@ -506,12 +507,13 @@ attributes #2 = { nobuiltin nounwind }
; CGSCC: attributes #[[ATTR4:[0-9]+]] = { nofree noinline nounwind memory(none) uwtable }
; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree noinline nosync nounwind willreturn memory(none) uwtable }
; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
-; CGSCC: attributes #[[ATTR7:[0-9]+]] = { nobuiltin nofree nounwind }
-; CGSCC: attributes #[[ATTR8]] = { nosync memory(none) }
-; CGSCC: attributes #[[ATTR9]] = { nosync memory(read) }
-; CGSCC: attributes #[[ATTR10]] = { nofree }
-; CGSCC: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
-; CGSCC: attributes #[[ATTR12:[0-9]+]] = { nounwind willreturn }
-; CGSCC: attributes #[[ATTR13]] = { nofree nosync willreturn }
-; CGSCC: attributes #[[ATTR14]] = { willreturn memory(write) }
+; CGSCC: attributes #[[ATTR7]] = { nofree nounwind }
+; CGSCC: attributes #[[ATTR8]] = { nobuiltin nofree nounwind }
+; CGSCC: attributes #[[ATTR9]] = { nosync memory(none) }
+; CGSCC: attributes #[[ATTR10]] = { nosync memory(read) }
+; CGSCC: attributes #[[ATTR11]] = { nofree }
+; CGSCC: attributes #[[ATTR12:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
+; CGSCC: attributes #[[ATTR13:[0-9]+]] = { nounwind willreturn }
+; CGSCC: attributes #[[ATTR14]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR15]] = { nofree willreturn memory(write) }
;.
diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index 0d48414b530ff..aa0cea33d02d0 100644
--- a/llvm/test/Transforms/Attributor/nonnull.ll
+++ b/llvm/test/Transforms/Attributor/nonnull.ll
@@ -1425,14 +1425,14 @@ define void @nonnull_assume_pos(ptr %arg) {
;
; TUNIT-LABEL: define {{[^@]+}}@nonnull_assume_pos
; TUNIT-SAME: (ptr nofree nonnull readnone captures(none) [[ARG:%.*]]) {
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR20:[0-9]+]] [ "nonnull"(ptr [[ARG]]) ]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16]] [ "nonnull"(ptr [[ARG]]) ]
; TUNIT-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[ARG]]) #[[ATTR5]]
; TUNIT-NEXT: [[TMP1:%.*]] = call ptr @unknown()
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define {{[^@]+}}@nonnull_assume_pos
; CGSCC-SAME: (ptr nofree nonnull readnone captures(none) [[ARG:%.*]]) {
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR21:[0-9]+]] [ "nonnull"(ptr [[ARG]]) ]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR16]] [ "nonnull"(ptr [[ARG]]) ]
; CGSCC-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[ARG]]) #[[ATTR4]]
; CGSCC-NEXT: [[TMP1:%.*]] = call ptr @unknown()
; CGSCC-NEXT: ret void
@@ -1554,14 +1554,14 @@ define void @phi_caller(ptr %p) {
; TUNIT: Function Attrs: nounwind
; TUNIT-LABEL: define {{[^@]+}}@phi_caller
; TUNIT-SAME: (ptr [[P:%.*]]) #[[ATTR5]] {
-; TUNIT-NEXT: [[C:%.*]] = call nonnull ptr @phi(ptr noalias nofree readnone [[P]]) #[[ATTR21:[0-9]+]]
+; TUNIT-NEXT: [[C:%.*]] = call nonnull ptr @phi(ptr noalias nofree readnone [[P]]) #[[ATTR20:[0-9]+]]
; TUNIT-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[C]]) #[[ATTR5]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nounwind
; CGSCC-LABEL: define {{[^@]+}}@phi_caller
; CGSCC-SAME: (ptr [[P:%.*]]) #[[ATTR4]] {
-; CGSCC-NEXT: [[C:%.*]] = call nonnull ptr @phi(ptr noalias nofree readnone [[P]]) #[[ATTR22:[0-9]+]]
+; CGSCC-NEXT: [[C:%.*]] = call nonnull ptr @phi(ptr noalias nofree readnone [[P]]) #[[ATTR21:[0-9]+]]
; CGSCC-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[C]]) #[[ATTR4]]
; CGSCC-NEXT: ret void
;
@@ -1594,14 +1594,14 @@ define void @multi_ret_caller(ptr %p) {
; TUNIT: Function Attrs: nounwind
; TUNIT-LABEL: define {{[^@]+}}@multi_ret_caller
; TUNIT-SAME: (ptr [[P:%.*]]) #[[ATTR5]] {
-; TUNIT-NEXT: [[C:%.*]] = call nonnull ptr @multi_ret(ptr noalias nofree readnone [[P]]) #[[ATTR21]]
+; TUNIT-NEXT: [[C:%.*]] = call nonnull ptr @multi_ret(ptr noalias nofree readnone [[P]]) #[[ATTR20]]
; TUNIT-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[C]]) #[[ATTR5]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nounwind
; CGSCC-LABEL: define {{[^@]+}}@multi_ret_caller
; CGSCC-SAME: (ptr [[P:%.*]]) #[[ATTR4]] {
-; CGSCC-NEXT: [[C:%.*]] = call nonnull ptr @multi_ret(ptr noalias nofree readnone [[P]]) #[[ATTR22]]
+; CGSCC-NEXT: [[C:%.*]] = call nonnull ptr @multi_ret(ptr noalias nofree readnone [[P]]) #[[ATTR21]]
; CGSCC-NEXT: call void @use_i8_ptr(ptr noalias nofree nonnull readnone captures(none) [[C]]) #[[ATTR4]]
; CGSCC-NEXT: ret void
;
@@ -1660,8 +1660,7 @@ attributes #1 = { nounwind willreturn}
; TUNIT: attributes #[[ATTR17]] = { nofree nosync nounwind memory(read) }
; TUNIT: attributes #[[ATTR18]] = { nosync willreturn memory(read) }
; TUNIT: attributes #[[ATTR19]] = { nofree nosync willreturn memory(read) }
-; TUNIT: attributes #[[ATTR20]] = { willreturn memory(write) }
-; TUNIT: attributes #[[ATTR21]] = { nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR20]] = { nofree nosync nounwind willreturn memory(none) }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
@@ -1684,8 +1683,7 @@ attributes #1 = { nounwind willreturn}
; CGSCC: attributes #[[ATTR18]] = { nosync willreturn memory(read) }
; CGSCC: attributes #[[ATTR19]] = { nofree nosync willreturn }
; CGSCC: attributes #[[ATTR20]] = { nofree nosync willreturn memory(read) }
-; CGSCC: attributes #[[ATTR21]] = { willreturn memory(write) }
-; CGSCC: attributes #[[ATTR22]] = { willreturn }
+; CGSCC: attributes #[[ATTR21]] = { willreturn }
;.
; TUNIT: [[META0]] = !{}
;.
diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll
index c4d51b7956560..503ceda37fc26 100644
--- a/llvm/test/Transforms/Attributor/range.ll
+++ b/llvm/test/Transforms/Attributor/range.ll
@@ -82,7 +82,7 @@ define void @test0-icmp-check(ptr %p){
; ret = [0, 10)
; TUNIT-LABEL: define {{[^@]+}}@test0-icmp-check
; TUNIT-SAME: (ptr nofree readonly align 4 captures(none) [[P:%.*]]) {
-; TUNIT-NEXT: [[RET:%.*]] = tail call range(i32 0, 10) i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR4:[0-9]+]]
+; TUNIT-NEXT: [[RET:%.*]] = tail call range(i32 0, 10) i32 @test0(ptr nofree noundef readonly align 4 captures(none) [[P]]) #[[ATTR3]]
; TUNIT-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
; TUNIT-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
; TUNIT-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
@@ -149,7 +149,7 @@ define void @test0-icmp-check(ptr %p){
;
; CGSCC-LABEL: define {{[^@]+}}@test0-icmp-check
; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P:%.*]]) {
-; CGSCC-NEXT: [[RET:%.*]] = tail call i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR6:[0-9]+]]
+; CGSCC-NEXT: [[RET:%.*]] = tail call i32 @test0(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[P]]) #[[ATTR5]]
; CGSCC-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
; CGSCC-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
; CGSCC-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
@@ -494,7 +494,7 @@ f:
define void @f1(i32){
; TUNIT-LABEL: define {{[^@]+}}@f1
; TUNIT-SAME: (i32 [[TMP0:%.*]]) {
-; TUNIT-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR5:[0-9]+]]
+; TUNIT-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR4:[0-9]+]]
; TUNIT-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
; TUNIT-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
; TUNIT: 4:
@@ -505,7 +505,7 @@ define void @f1(i32){
;
; CGSCC-LABEL: define {{[^@]+}}@f1
; CGSCC-SAME: (i32 [[TMP0:%.*]]) {
-; CGSCC-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR7:[0-9]+]]
+; CGSCC-NEXT: [[TMP2:%.*]] = tail call i32 @r1() #[[ATTR6:[0-9]+]]
; CGSCC-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
; CGSCC-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
; CGSCC: 4:
@@ -580,14 +580,14 @@ define dso_local i32 @test4-g1(i32 %u) {
; TUNIT-LABEL: define {{[^@]+}}@test4-g1
; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR5]]
+; TUNIT-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR4]]
; TUNIT-NEXT: ret i32 [[CALL]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@test4-g1
; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3:[0-9]+]] {
; CGSCC-NEXT: entry:
-; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR8:[0-9]+]]
+; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) #[[ATTR7:[0-9]+]]
; CGSCC-NEXT: ret i32 [[CALL]]
;
; FIXME: %call should have range [0, inf]
@@ -658,14 +658,14 @@ define dso_local i32 @test4-g2(i32 %u) {
; TUNIT-LABEL: define {{[^@]+}}@test4-g2
; TUNIT-SAME: (i32 [[U:%.*]]) #[[ATTR1]] {
; TUNIT-NEXT: entry:
-; TUNIT-NEXT: [[CALL:%.*]] = tail call range(i32 1, -2147483648) i32 @test4-f2(i32 [[U]]) #[[ATTR5]]
+; TUNIT-NEXT: [[CALL:%.*]] = tail call range(i32 1, -2147483648) i32 @test4-f2(i32 [[U]]) #[[ATTR4]]
; TUNIT-NEXT: ret i32 [[CALL]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@test4-g2
; CGSCC-SAME: (i32 [[U:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: entry:
-; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR8]]
+; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #[[ATTR7]]
; CGSCC-NEXT: ret i32 [[CALL]]
;
entry:
@@ -1006,10 +1006,10 @@ define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, ptr %dpa, p
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@fcmp_caller
; TUNIT-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR1]] {
-; TUNIT-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR5]]
-; TUNIT-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR5]]
-; TUNIT-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR5]]
-; TUNIT-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR5]]
+; TUNIT-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR4]]
+; TUNIT-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR4]]
+; TUNIT-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR4]]
+; TUNIT-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR4]]
; TUNIT-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
; TUNIT-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
; TUNIT-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
@@ -1018,10 +1018,10 @@ define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, ptr %dpa, p
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@fcmp_caller
; CGSCC-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], ptr nofree readnone [[DPA:%.*]], ptr nofree readnone [[DPB:%.*]], ptr nofree readnone [[IPA:%.*]], ptr nofree readnone [[IPB:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR8]]
-; CGSCC-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR8]]
-; CGSCC-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR8]]
-; CGSCC-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR8]]
+; CGSCC-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) #[[ATTR7]]
+; CGSCC-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) #[[ATTR7]]
+; CGSCC-NEXT: [[R3:%.*]] = call i1 @dp_icmp(ptr noalias nofree readnone [[DPA]], ptr noalias nofree readnone [[DPB]]) #[[ATTR7]]
+; CGSCC-NEXT: [[R4:%.*]] = call i1 @ip_icmp(ptr noalias nofree readnone [[IPA]], ptr noalias nofree readnone [[IPB]]) #[[ATTR7]]
; CGSCC-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
; CGSCC-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
; CGSCC-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
@@ -1074,7 +1074,7 @@ define i8 @undef_collapse_1() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_1
; CGSCC-SAME: () #[[ATTR3]] {
-; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_undef() #[[ATTR8]]
+; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_undef() #[[ATTR7]]
; CGSCC-NEXT: [[S:%.*]] = shl i8 [[C]], 2
; CGSCC-NEXT: ret i8 [[S]]
;
@@ -1093,7 +1093,7 @@ define i8 @undef_collapse_2() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_2
; CGSCC-SAME: () #[[ATTR3]] {
-; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_two() #[[ATTR8]]
+; CGSCC-NEXT: [[C:%.*]] = call i8 @ret_two() #[[ATTR7]]
; CGSCC-NEXT: [[S:%.*]] = shl i8 undef, [[C]]
; CGSCC-NEXT: ret i8 [[S]]
;
@@ -1112,8 +1112,8 @@ define i8 @undef_collapse_caller() {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@undef_collapse_caller
; CGSCC-SAME: () #[[ATTR3]] {
-; CGSCC-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR8]]
-; CGSCC-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR8]]
+; CGSCC-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1() #[[ATTR7]]
+; CGSCC-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2() #[[ATTR7]]
; CGSCC-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]]
; CGSCC-NEXT: ret i8 [[A]]
;
@@ -1144,8 +1144,8 @@ define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@callee_range_1
; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR1]] {
-; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR5]]
-; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR5]]
+; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]
+; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]
; TUNIT-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]
; TUNIT-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
; TUNIT-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4
@@ -1156,8 +1156,8 @@ define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@callee_range_1
; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR8]]
-; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR8]]
+; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]
+; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]
; CGSCC-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32 [[R1]], i32 [[R2]]
; CGSCC-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
; CGSCC-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4
@@ -1180,8 +1180,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@callee_range_2
; TUNIT-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] {
-; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR5]]
-; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR5]]
+; TUNIT-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR4]]
+; TUNIT-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR4]]
; TUNIT-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
; TUNIT-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
; TUNIT-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
@@ -1191,8 +1191,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@callee_range_2
; CGSCC-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR8]]
-; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR8]]
+; CGSCC-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #[[ATTR7]]
+; CGSCC-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #[[ATTR7]]
; CGSCC-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
; CGSCC-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
; CGSCC-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
@@ -1247,7 +1247,7 @@ define i1 @ctx_adjustment(i32 %V) {
; CGSCC: if.true:
; CGSCC-NEXT: br label [[END:%.*]]
; CGSCC: if.false:
-; CGSCC-NEXT: [[CALL:%.*]] = call i32 @ret100() #[[ATTR8]]
+; CGSCC-NEXT: [[CALL:%.*]] = call i32 @ret100() #[[ATTR7]]
; CGSCC-NEXT: br label [[END]]
; CGSCC: end:
; CGSCC-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ [[CALL]], [[IF_FALSE]] ]
@@ -1292,10 +1292,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; TUNIT-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
-; TUNIT-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR5]]
+; TUNIT-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) #[[ATTR4]]
; TUNIT-NEXT: ret i32 [[RET1]]
; TUNIT: f:
-; TUNIT-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR5]]
+; TUNIT-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) #[[ATTR4]]
; TUNIT-NEXT: ret i32 [[RET2]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
@@ -1304,10 +1304,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
; CGSCC-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
-; CGSCC-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR8]]
+; CGSCC-NEXT: [[RET1:%.*]] = call noundef i32 @func(i1 noundef [[C]]) #[[ATTR7]]
; CGSCC-NEXT: ret i32 [[RET1]]
; CGSCC: f:
-; CGSCC-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR8]]
+; CGSCC-NEXT: [[RET2:%.*]] = call noundef i32 @func(i1 noundef false) #[[ATTR7]]
; CGSCC-NEXT: ret i32 [[RET2]]
;
%c = select i1 %d, i1 true, i1 false
@@ -1352,10 +1352,10 @@ define i1 @check_divided_range(i32 %arg) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@check_divided_range
; CGSCC-SAME: (i32 [[ARG:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR8]]
-; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR8]]
-; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR8]]
-; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR8]]
+; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) #[[ATTR7]]
+; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) #[[ATTR7]]
+; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) #[[ATTR7]]
+; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) #[[ATTR7]]
; CGSCC-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; CGSCC-NEXT: ret i1 [[RET]]
;
@@ -1399,10 +1399,10 @@ define i1 @check_casted_range(i1 %c) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@check_casted_range
; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR8]]
-; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR8]]
+; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @cast_and_return(i1 noundef true) #[[ATTR7]]
+; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @cast_and_return(i1 [[C]]) #[[ATTR7]]
; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[CSRET1]], [[CSRET2]]
-; CGSCC-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR8]]
+; CGSCC-NEXT: [[RET:%.*]] = call i1 @is_less_than_3(i32 [[ADD]]) #[[ATTR7]]
; CGSCC-NEXT: ret i1 [[RET]]
;
%csret1 = call i32 @cast_and_return(i1 true)
@@ -1487,8 +1487,8 @@ define i1 @propagate_range1(i32 %c){
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@propagate_range1
; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 noundef [[C]]) #[[ATTR8]]
-; CGSCC-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR8]]
+; CGSCC-NEXT: [[CSRET:%.*]] = call i32 @less_than_100_1(i32 noundef [[C]]) #[[ATTR7]]
+; CGSCC-NEXT: [[TRUE:%.*]] = call i1 @is_less_than_100_1(i32 noundef [[CSRET]]) #[[ATTR7]]
; CGSCC-NEXT: ret i1 [[TRUE]]
;
%csret = call i32 @less_than_100_1(i32 %c)
@@ -1603,20 +1603,20 @@ define i1 @propagate_range2(i32 %c) {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@propagate_range2
; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
-; TUNIT-NEXT: [[CSRET1:%.*]] = call noundef i32 @less_than_100_2(i32 noundef 0) #[[ATTR5]]
-; TUNIT-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR5]]
-; TUNIT-NEXT: [[CSRET2:%.*]] = call noundef i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR5]]
-; TUNIT-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR5]]
+; TUNIT-NEXT: [[CSRET1:%.*]] = call noundef i32 @less_than_100_2(i32 noundef 0) #[[ATTR4]]
+; TUNIT-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR4]]
+; TUNIT-NEXT: [[CSRET2:%.*]] = call noundef i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR4]]
+; TUNIT-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR4]]
; TUNIT-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; TUNIT-NEXT: ret i1 [[TRUE]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@propagate_range2
; CGSCC-SAME: (i32 noundef [[C:%.*]]) #[[ATTR3]] {
-; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR8]]
-; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR8]]
-; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR8]]
-; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR8]]
+; CGSCC-NEXT: [[CSRET1:%.*]] = call i32 @less_than_100_2(i32 noundef 0) #[[ATTR7]]
+; CGSCC-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET1]]) #[[ATTR7]]
+; CGSCC-NEXT: [[CSRET2:%.*]] = call i32 @less_than_100_2(i32 noundef [[C]]) #[[ATTR7]]
+; CGSCC-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_100_2(i32 noundef [[CSRET2]]) #[[ATTR7]]
; CGSCC-NEXT: [[TRUE:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
; CGSCC-NEXT: ret i1 [[TRUE]]
;
@@ -1653,7 +1653,7 @@ define i1 @context(ptr %p) {
; TUNIT-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]
; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
-; TUNIT-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR5]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) #[[ATTR4]]
; TUNIT-NEXT: ret i1 [[R]]
; TUNIT: f:
; TUNIT-NEXT: ret i1 false
@@ -1665,7 +1665,7 @@ define i1 @context(ptr %p) {
; CGSCC-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]
; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
-; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @non_zero(i8 [[L]]) #[[ATTR8]]
+; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @non_zero(i8 [[L]]) #[[ATTR7]]
; CGSCC-NEXT: ret i1 [[R]]
; CGSCC: f:
; CGSCC-NEXT: ret i1 false
@@ -1800,8 +1800,7 @@ declare void @barney(i32 signext, i32 signext)
; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
; TUNIT: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind memory(none) }
; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn memory(read) }
-; TUNIT: attributes #[[ATTR4]] = { nosync nounwind willreturn memory(read) }
-; TUNIT: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(none) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: read) }
@@ -1809,9 +1808,8 @@ declare void @barney(i32 signext, i32 signext)
; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind memory(none) }
; CGSCC: attributes #[[ATTR5]] = { nofree willreturn memory(read) }
-; CGSCC: attributes #[[ATTR6]] = { willreturn memory(read) }
-; CGSCC: attributes #[[ATTR7]] = { willreturn }
-; CGSCC: attributes #[[ATTR8]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR6]] = { willreturn }
+; CGSCC: attributes #[[ATTR7]] = { nofree nosync willreturn }
;.
; TUNIT: [[RNG0]] = !{i32 0, i32 10}
; TUNIT: [[RNG1]] = !{i32 10, i32 100}
diff --git a/llvm/test/Transforms/Attributor/value-simplify-assume.ll b/llvm/test/Transforms/Attributor/value-simplify-assume.ll
index 886674cd07581..c1ffb599febf6 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-assume.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-assume.ll
@@ -94,7 +94,7 @@ define i1 @keep_assume_3c_nr() norecurse {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8:[0-9]+]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -104,7 +104,7 @@ define i1 @keep_assume_3c_nr() norecurse {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9:[0-9]+]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -122,7 +122,7 @@ define i1 @keep_assume_4c_nr() norecurse {
; TUNIT-SAME: () #[[ATTR2]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 true
;
@@ -131,7 +131,7 @@ define i1 @keep_assume_4c_nr() norecurse {
; CGSCC-SAME: () #[[ATTR2]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR9]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]
; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 true
;
@@ -217,7 +217,7 @@ define i1 @keep_assume_3_nr(i1 %arg) norecurse {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -227,7 +227,7 @@ define i1 @keep_assume_3_nr(i1 %arg) norecurse {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -246,7 +246,7 @@ define i1 @keep_assume_4_nr(i1 %arg) norecurse {
; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[ARG]]
;
@@ -255,7 +255,7 @@ define i1 @keep_assume_4_nr(i1 %arg) norecurse {
; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR9]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[ARG]]
;
@@ -428,7 +428,7 @@ define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse {
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9:[0-9]+]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8:[0-9]+]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -446,7 +446,7 @@ define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse {
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10:[0-9]+]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9:[0-9]+]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -480,7 +480,7 @@ define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse {
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -498,7 +498,7 @@ define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse {
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -535,8 +535,8 @@ define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse {
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10:[0-9]+]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9:[0-9]+]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -550,17 +550,17 @@ define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse {
; CGSCC: t:
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR11:[0-9]+]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10:[0-9]+]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR11]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -604,8 +604,8 @@ define i1 @assume_5c_nr(i1 %cond) norecurse {
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -619,17 +619,17 @@ define i1 @assume_5c_nr(i1 %cond) norecurse {
; CGSCC: t:
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR11]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -719,7 +719,7 @@ define i1 @keep_assume_3c() {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -727,7 +727,7 @@ define i1 @keep_assume_3c() {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -744,7 +744,7 @@ define i1 @keep_assume_4c() {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR7]]
; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L4]]
;
@@ -752,7 +752,7 @@ define i1 @keep_assume_4c() {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR8]]
; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L4]]
;
@@ -835,7 +835,7 @@ define i1 @keep_assume_3(i1 %arg) {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
; TUNIT-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -844,7 +844,7 @@ define i1 @keep_assume_3(i1 %arg) {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -863,7 +863,7 @@ define i1 @keep_assume_4(i1 %arg) {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
; TUNIT-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
@@ -872,7 +872,7 @@ define i1 @keep_assume_4(i1 %arg) {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR9]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
; CGSCC-NEXT: call void @useI1p(ptr noalias noundef nonnull captures(none) dereferenceable(1) [[STACK]])
; CGSCC-NEXT: ret i1 [[L]]
;
@@ -1045,7 +1045,7 @@ define i1 @assume_3(i1 %arg, i1 %cond) {
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -1063,7 +1063,7 @@ define i1 @assume_3(i1 %arg, i1 %cond) {
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -1097,7 +1097,7 @@ define i1 @assume_4(i1 %arg, i1 %cond) {
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -1115,7 +1115,7 @@ define i1 @assume_4(i1 %arg, i1 %cond) {
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -1152,8 +1152,8 @@ define i1 @assume_5(i1 %arg, i1 %cond) {
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -1167,17 +1167,17 @@ define i1 @assume_5(i1 %arg, i1 %cond) {
; CGSCC: t:
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR11]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -1221,8 +1221,8 @@ define i1 @assume_5c(i1 %cond) {
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
-; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR9]]
+; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
+; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR8]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
@@ -1236,17 +1236,17 @@ define i1 @assume_5c(i1 %cond) {
; CGSCC: t:
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR11]]
-; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR11]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[STACK]]) #[[ATTR10]]
; CGSCC-NEXT: ret i1 [[R]]
;
%stack = alloca i1
@@ -1373,9 +1373,8 @@ define void @assume_write_globals() {
; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn }
; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
; TUNIT: attributes #[[ATTR7]] = { nofree willreturn memory(write) }
-; TUNIT: attributes #[[ATTR8]] = { willreturn memory(write) }
-; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn memory(read) }
-; TUNIT: attributes #[[ATTR10]] = { nofree willreturn }
+; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn memory(read) }
+; TUNIT: attributes #[[ATTR9]] = { nofree willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
@@ -1386,7 +1385,6 @@ define void @assume_write_globals() {
; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn }
; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
; CGSCC: attributes #[[ATTR8]] = { nofree willreturn memory(write) }
-; CGSCC: attributes #[[ATTR9]] = { willreturn memory(write) }
-; CGSCC: attributes #[[ATTR10]] = { nofree willreturn memory(read) }
-; CGSCC: attributes #[[ATTR11]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR9]] = { nofree willreturn memory(read) }
+; CGSCC: attributes #[[ATTR10]] = { nofree willreturn }
;.
diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
index 7e8c304512772..caf57217d5114 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
@@ -1528,8 +1528,8 @@ define i32 @local_alloca_not_simplifiable_1() {
; TUNIT-NEXT: [[ENTRY:.*:]]
; TUNIT-NEXT: [[X:%.*]] = alloca i32, align 4
; TUNIT-NEXT: [[Y:%.*]] = alloca i32, align 4
-; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR19:[0-9]+]]
-; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR19]]
+; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR17]]
+; TUNIT-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR17]]
; TUNIT-NEXT: store i32 1, ptr [[Y]], align 4, !tbaa [[INT_TBAA3]]
; TUNIT-NEXT: store i32 1, ptr [[X]], align 4, !tbaa [[INT_TBAA3]]
; TUNIT-NEXT: call void @escape(ptr noundef nonnull align 4 dereferenceable(4) [[X]])
@@ -1548,8 +1548,8 @@ define i32 @local_alloca_not_simplifiable_1() {
; CGSCC-NEXT: [[ENTRY:.*:]]
; CGSCC-NEXT: [[X:%.*]] = alloca i32, align 4
; CGSCC-NEXT: [[Y:%.*]] = alloca i32, align 4
-; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR22:[0-9]+]]
-; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR22]]
+; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR20]]
+; CGSCC-NEXT: call void @llvm.lifetime.start.p0(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]]) #[[ATTR20]]
; CGSCC-NEXT: store i32 1, ptr [[Y]], align 4, !tbaa [[INT_TBAA3]]
; CGSCC-NEXT: store i32 1, ptr [[X]], align 4, !tbaa [[INT_TBAA3]]
; CGSCC-NEXT: call void @escape(ptr noundef nonnull align 4 dereferenceable(4) [[X]])
@@ -1810,7 +1810,7 @@ define i32 @static_global_not_simplifiable_2(i32 %cnd) {
; TUNIT-SAME: i32 [[CND:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
; TUNIT-NEXT: store i32 1, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
-; TUNIT-NEXT: call void @sync() #[[ATTR20:[0-9]+]]
+; TUNIT-NEXT: call void @sync() #[[ATTR19:[0-9]+]]
; TUNIT-NEXT: [[I:%.*]] = load i32, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
; TUNIT-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
; TUNIT-NEXT: ret i32 [[I]]
@@ -1819,7 +1819,7 @@ define i32 @static_global_not_simplifiable_2(i32 %cnd) {
; CGSCC-SAME: i32 [[CND:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
; CGSCC-NEXT: store i32 1, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
-; CGSCC-NEXT: call void @sync() #[[ATTR23:[0-9]+]]
+; CGSCC-NEXT: call void @sync() #[[ATTR22:[0-9]+]]
; CGSCC-NEXT: [[I:%.*]] = load i32, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
; CGSCC-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[INT_TBAA3]]
; CGSCC-NEXT: ret i32 [[I]]
@@ -2521,14 +2521,14 @@ define dso_local ptr @malloc_like(i32 %s) {
; TUNIT-SAME: i32 [[S:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
; TUNIT-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64
-; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR21:[0-9]+]]
+; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR20:[0-9]+]]
; TUNIT-NEXT: ret ptr [[CALL]]
;
; CGSCC-LABEL: define dso_local noalias ptr @malloc_like(
; CGSCC-SAME: i32 [[S:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
; CGSCC-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64
-; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR24:[0-9]+]]
+; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR23:[0-9]+]]
; CGSCC-NEXT: ret ptr [[CALL]]
;
entry:
@@ -2541,19 +2541,19 @@ define dso_local i32 @round_trip_malloc_like(i32 %x) {
; TUNIT-LABEL: define dso_local i32 @round_trip_malloc_like(
; TUNIT-SAME: i32 [[X:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
-; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR21]]
+; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR20]]
; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR21]]
+; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]]
; TUNIT-NEXT: ret i32 [[TMP0]]
;
; CGSCC-LABEL: define dso_local i32 @round_trip_malloc_like(
; CGSCC-SAME: i32 [[X:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
-; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR24]]
+; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR23]]
; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24]]
+; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]]
; CGSCC-NEXT: ret i32 [[TMP0]]
;
entry:
@@ -2568,19 +2568,19 @@ define dso_local i32 @round_trip_unknown_alloc(i32 %x) {
; TUNIT-LABEL: define dso_local i32 @round_trip_unknown_alloc(
; TUNIT-SAME: i32 [[X:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
-; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR21]]
+; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR20]]
; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR21]]
+; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]]
; TUNIT-NEXT: ret i32 [[TMP0]]
;
; CGSCC-LABEL: define dso_local i32 @round_trip_unknown_alloc(
; CGSCC-SAME: i32 [[X:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
-; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR24]]
+; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR23]]
; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24]]
+; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]]
; CGSCC-NEXT: ret i32 [[TMP0]]
;
entry:
@@ -2597,7 +2597,7 @@ define dso_local i32 @conditional_unknown_alloc(i32 %x) {
; TUNIT-LABEL: define dso_local i32 @conditional_unknown_alloc(
; TUNIT-SAME: i32 [[X:%.*]]) {
; TUNIT-NEXT: [[ENTRY:.*:]]
-; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR21]]
+; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR20]]
; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
; TUNIT-NEXT: br i1 [[TOBOOL]], label %[[IF_END:.*]], label %[[IF_THEN:.*]]
; TUNIT: [[IF_THEN]]:
@@ -2605,13 +2605,13 @@ define dso_local i32 @conditional_unknown_alloc(i32 %x) {
; TUNIT-NEXT: br label %[[IF_END]]
; TUNIT: [[IF_END]]:
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; TUNIT-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR21]]
+; TUNIT-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]]
; TUNIT-NEXT: ret i32 [[TMP0]]
;
; CGSCC-LABEL: define dso_local i32 @conditional_unknown_alloc(
; CGSCC-SAME: i32 [[X:%.*]]) {
; CGSCC-NEXT: [[ENTRY:.*:]]
-; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR24]]
+; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR23]]
; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
; CGSCC-NEXT: br i1 [[TOBOOL]], label %[[IF_END:.*]], label %[[IF_THEN:.*]]
; CGSCC: [[IF_THEN]]:
@@ -2619,7 +2619,7 @@ define dso_local i32 @conditional_unknown_alloc(i32 %x) {
; CGSCC-NEXT: br label %[[IF_END]]
; CGSCC: [[IF_END]]:
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
-; CGSCC-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR24]]
+; CGSCC-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]]
; CGSCC-NEXT: ret i32 [[TMP0]]
;
entry:
@@ -2659,7 +2659,7 @@ define dso_local void @test_nested_memory(ptr %dst, ptr %src) {
; TUNIT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[LOCAL_B8]], align 8
; TUNIT-NEXT: [[LOCAL_B16:%.*]] = getelementptr i8, ptr [[LOCAL]], i64 16
; TUNIT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[LOCAL_B16]], align 8
-; TUNIT-NEXT: call fastcc void @nested_memory_callee(ptr [[TMP0]], ptr [[TMP1]], ptr [[TMP2]]) #[[ATTR22:[0-9]+]]
+; TUNIT-NEXT: call fastcc void @nested_memory_callee(ptr [[TMP0]], ptr [[TMP1]], ptr [[TMP2]]) #[[ATTR21:[0-9]+]]
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define dso_local void @test_nested_memory(
@@ -2672,7 +2672,7 @@ define dso_local void @test_nested_memory(ptr %dst, ptr %src) {
; CGSCC-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
; CGSCC-NEXT: store ptr [[SRC]], ptr [[SRC2]], align 8
; CGSCC-NEXT: store ptr [[CALL]], ptr getelementptr inbounds ([[STRUCT_STY]], ptr @global, i64 0, i32 2), align 8
-; CGSCC-NEXT: call fastcc void @nested_memory_callee(ptr nofree align 4294967296 undef, ptr nofree align 4294967296 undef, ptr nofree noundef nonnull align 8 dereferenceable(24) @global) #[[ATTR25:[0-9]+]]
+; CGSCC-NEXT: call fastcc void @nested_memory_callee(ptr nofree align 4294967296 undef, ptr nofree align 4294967296 undef, ptr nofree noundef nonnull align 8 dereferenceable(24) @global) #[[ATTR24:[0-9]+]]
; CGSCC-NEXT: ret void
;
entry:
@@ -2933,7 +2933,7 @@ define i1 @alloca_non_unique_caller(i32 %in, i1 %c) {
; CGSCC: Function Attrs: nofree nosync nounwind memory(none)
; CGSCC-LABEL: define i1 @alloca_non_unique_caller(
; CGSCC-SAME: i32 [[IN:%.*]], i1 noundef [[C:%.*]]) #[[ATTR15:[0-9]+]] {
-; CGSCC-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr nofree undef, i32 [[IN]], i1 noundef [[C]]) #[[ATTR26:[0-9]+]]
+; CGSCC-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr nofree undef, i32 [[IN]], i1 noundef [[C]]) #[[ATTR25:[0-9]+]]
; CGSCC-NEXT: ret i1 [[R]]
;
%r = call i1 @alloca_non_unique(ptr undef, i32 %in, i1 %c)
@@ -2947,7 +2947,7 @@ define i32 @scope_value_traversal(i32 %bad, i1 %c, i1 %c2) {
; TUNIT-SAME: i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR4]] {
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
; TUNIT-NEXT: store i32 [[BAD]], ptr [[A]], align 4
-; TUNIT-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR23:[0-9]+]]
+; TUNIT-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR22:[0-9]+]]
; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4
; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]]
; TUNIT-NEXT: ret i32 [[SEL]]
@@ -2957,7 +2957,7 @@ define i32 @scope_value_traversal(i32 %bad, i1 %c, i1 %c2) {
; CGSCC-SAME: i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR16:[0-9]+]] {
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
; CGSCC-NEXT: store i32 [[BAD]], ptr [[A]], align 4
-; CGSCC-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR27:[0-9]+]]
+; CGSCC-NEXT: call void @scope_value_traversal_helper(ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR26:[0-9]+]]
; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4
; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]]
; CGSCC-NEXT: ret i32 [[SEL]]
@@ -3145,8 +3145,8 @@ define i32 @recSimplify(i32 %v, i1 %cond) {
; CGSCC-NEXT: store i32 1, ptr @GRS2, align 4
; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @GRS, align 4
; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 1
-; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR28:[0-9]+]]
-; CGSCC-NEXT: [[R:%.*]] = call i32 @recSimplify2() #[[ATTR28]]
+; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR27:[0-9]+]]
+; CGSCC-NEXT: [[R:%.*]] = call i32 @recSimplify2() #[[ATTR27]]
; CGSCC-NEXT: ret i32 [[R]]
;
br i1 %cond, label %rec, label %comp
@@ -3245,8 +3245,8 @@ define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c
; TUNIT-NEXT: [[ENTRY:.*:]]
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
-; TUNIT-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]]) #[[ATTR24:[0-9]+]]
-; TUNIT-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR24]]
+; TUNIT-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]]) #[[ATTR23:[0-9]+]]
+; TUNIT-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
; TUNIT-NEXT: call void @write_both(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL1]]) #[[ATTR18]]
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
@@ -3259,8 +3259,8 @@ define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c
; CGSCC-NEXT: [[ENTRY:.*:]]
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
-; CGSCC-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]]) #[[ATTR29:[0-9]+]]
-; CGSCC-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]]) #[[ATTR29]]
+; CGSCC-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]]) #[[ATTR28:[0-9]+]]
+; CGSCC-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]]) #[[ATTR28]]
; CGSCC-NEXT: call void @write_both(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL1]]) #[[ATTR21]]
; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
@@ -3450,9 +3450,9 @@ declare void @use3i8(i8, i8, i8)
define void @returnedPtrAccesses() {
; TUNIT-LABEL: define void @returnedPtrAccesses() {
; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8
-; TUNIT-NEXT: [[A2:%.*]] = call ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR25:[0-9]+]]
-; TUNIT-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR25]]
-; TUNIT-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree readnone "no-capture-maybe-returned" [[A2]]) #[[ATTR25]]
+; TUNIT-NEXT: [[A2:%.*]] = call ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
+; TUNIT-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
+; TUNIT-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree readnone "no-capture-maybe-returned" [[A2]]) #[[ATTR23]]
; TUNIT-NEXT: store i8 2, ptr [[A2]], align 1
; TUNIT-NEXT: store i8 4, ptr [[A4]], align 1
; TUNIT-NEXT: store i8 6, ptr [[A6]], align 1
@@ -3461,9 +3461,9 @@ define void @returnedPtrAccesses() {
;
; CGSCC-LABEL: define void @returnedPtrAccesses() {
; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8
-; CGSCC-NEXT: [[A2:%.*]] = call nonnull dereferenceable(1) ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR22]]
-; CGSCC-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR22]]
-; CGSCC-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone dereferenceable(1) [[A2]]) #[[ATTR22]]
+; CGSCC-NEXT: [[A2:%.*]] = call nonnull dereferenceable(1) ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR29:[0-9]+]]
+; CGSCC-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR29]]
+; CGSCC-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone dereferenceable(1) [[A2]]) #[[ATTR29]]
; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2
; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4
; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6
@@ -3497,7 +3497,7 @@ define void @returnedPtrAccessesMultiple(i32 %i) {
; TUNIT-LABEL: define void @returnedPtrAccessesMultiple(
; TUNIT-SAME: i32 [[I:%.*]]) {
; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8
-; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR25]]
+; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
; TUNIT-NEXT: store i8 2, ptr [[AP]], align 1
; TUNIT-NEXT: call void @use3i8(i8 2, i8 2, i8 2)
; TUNIT-NEXT: ret void
@@ -3505,7 +3505,7 @@ define void @returnedPtrAccessesMultiple(i32 %i) {
; CGSCC-LABEL: define void @returnedPtrAccessesMultiple(
; CGSCC-SAME: i32 [[I:%.*]]) {
; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8
-; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR22]]
+; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR29]]
; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2
; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4
; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6
@@ -3539,7 +3539,7 @@ define void @returnedPtrAccessesMultiple2(i32 %i) {
; TUNIT-NEXT: store i8 0, ptr [[G2]], align 2
; TUNIT-NEXT: store i8 0, ptr [[G4]], align 4
; TUNIT-NEXT: store i8 0, ptr [[G6]], align 2
-; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR25]]
+; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
; TUNIT-NEXT: store i8 2, ptr [[AP]], align 1
; TUNIT-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2
; TUNIT-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4
@@ -3556,7 +3556,7 @@ define void @returnedPtrAccessesMultiple2(i32 %i) {
; CGSCC-NEXT: store i8 0, ptr [[G2]], align 2
; CGSCC-NEXT: store i8 0, ptr [[G4]], align 4
; CGSCC-NEXT: store i8 0, ptr [[G6]], align 2
-; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR22]]
+; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR29]]
; CGSCC-NEXT: store i8 2, ptr [[AP]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2
; CGSCC-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4
@@ -3638,13 +3638,11 @@ declare void @llvm.assume(i1 noundef)
; TUNIT: attributes #[[ATTR16:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }
; TUNIT: attributes #[[ATTR17]] = { nofree willreturn }
; TUNIT: attributes #[[ATTR18]] = { nofree nosync nounwind willreturn memory(write) }
-; TUNIT: attributes #[[ATTR19]] = { willreturn }
-; TUNIT: attributes #[[ATTR20]] = { nocallback }
-; TUNIT: attributes #[[ATTR21]] = { norecurse }
-; TUNIT: attributes #[[ATTR22]] = { nounwind }
-; TUNIT: attributes #[[ATTR23]] = { nofree nosync nounwind willreturn }
-; TUNIT: attributes #[[ATTR24]] = { nofree nosync nounwind willreturn memory(none) }
-; TUNIT: attributes #[[ATTR25]] = { nosync nounwind willreturn memory(none) }
+; TUNIT: attributes #[[ATTR19]] = { nocallback }
+; TUNIT: attributes #[[ATTR20]] = { norecurse }
+; TUNIT: attributes #[[ATTR21]] = { nounwind }
+; TUNIT: attributes #[[ATTR22]] = { nofree nosync nounwind willreturn }
+; TUNIT: attributes #[[ATTR23]] = { nofree nosync nounwind willreturn memory(none) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) }
@@ -3668,14 +3666,14 @@ declare void @llvm.assume(i1 noundef)
; CGSCC: attributes #[[ATTR19:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }
; CGSCC: attributes #[[ATTR20]] = { nofree willreturn }
; CGSCC: attributes #[[ATTR21]] = { nofree nounwind willreturn memory(write) }
-; CGSCC: attributes #[[ATTR22]] = { willreturn }
-; CGSCC: attributes #[[ATTR23]] = { nocallback }
-; CGSCC: attributes #[[ATTR24]] = { norecurse }
-; CGSCC: attributes #[[ATTR25]] = { nounwind }
-; CGSCC: attributes #[[ATTR26]] = { nofree nounwind }
-; CGSCC: attributes #[[ATTR27]] = { nofree nounwind willreturn }
-; CGSCC: attributes #[[ATTR28]] = { nofree }
-; CGSCC: attributes #[[ATTR29]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR22]] = { nocallback }
+; CGSCC: attributes #[[ATTR23]] = { norecurse }
+; CGSCC: attributes #[[ATTR24]] = { nounwind }
+; CGSCC: attributes #[[ATTR25]] = { nofree nounwind }
+; CGSCC: attributes #[[ATTR26]] = { nofree nounwind willreturn }
+; CGSCC: attributes #[[ATTR27]] = { nofree }
+; CGSCC: attributes #[[ATTR28]] = { nofree nosync willreturn }
+; CGSCC: attributes #[[ATTR29]] = { willreturn }
;.
; TUNIT: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; TUNIT: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1}
diff --git a/llvm/test/Transforms/OpenMP/parallel_deletion.ll b/llvm/test/Transforms/OpenMP/parallel_deletion.ll
index bb6b0379a0952..9d4eb7faa8256 100644
--- a/llvm/test/Transforms/OpenMP/parallel_deletion.ll
+++ b/llvm/test/Transforms/OpenMP/parallel_deletion.ll
@@ -282,7 +282,7 @@ define void @delete_parallel_2() {
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR15]]
+; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr noundef nonnull align 4 dereferenceable(4) [[A]]) #[[ATTR18:[0-9]+]]
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..3, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]])
; CHECK-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr noundef nonnull align 8 dereferenceable(24) @[[GLOB0]], i32 noundef 1, ptr noundef nonnull @.omp_outlined..4, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A]])
@@ -329,7 +329,7 @@ define internal void @.omp_outlined..3(ptr noalias %.global_tid., ptr noalias %.
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3
; CHECK-SAME: (ptr noalias nofree readnone captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR18:[0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #[[ATTR19:[0-9]+]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
@@ -457,7 +457,7 @@ define internal void @.omp_outlined..5(ptr noalias %.global_tid., ptr noalias %.
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
; CHECK-SAME: (ptr noalias nofree readonly captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias nofree readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[A:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR19:[0-9]+]]
+; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(ptr noundef nonnull @[[GLOB0]]) #[[ATTR19]]
; CHECK-NEXT: [[TMP:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4, !invariant.load [[META1]]
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(ptr noundef nonnull @[[GLOB0]], i32 [[TMP]])
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
>From feb22cecf19d52dcca190cc5f51e788e0ae99dfb Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 28 May 2026 08:58:16 +0200
Subject: [PATCH 4/4] Address nit
---
llvm/lib/Transforms/IPO/AttributorAttributes.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index d9a886eaa236b..004bd3f741dd8 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -2366,7 +2366,8 @@ struct AANoFreeFloating : AANoFreeImpl {
const AANoCapture *NoCaptureAA = nullptr;
if (!AA::hasAssumedIRAttr<Attribute::Captures>(
A, this, IRPosition::callsite_argument(*CB, ArgNo),
- DepClassTy::REQUIRED, IsKnown, false, &NoCaptureAA)) {
+ DepClassTy::REQUIRED, IsKnown,
+ /*IgnoreSubsumingPositions=*/false, &NoCaptureAA)) {
if (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
Follow = true;
return true;
More information about the cfe-commits
mailing list