[clang] 91d765f - [FunctionAttrs][Attributor] Update nofree inference (#196266)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 28 00:41:47 PDT 2026
Author: Nikita Popov
Date: 2026-05-28T07:41:35Z
New Revision: 91d765f6ab10974f2c7080c90fe26b21bd7d7cb1
URL: https://github.com/llvm/llvm-project/commit/91d765f6ab10974f2c7080c90fe26b21bd7d7cb1
DIFF: https://github.com/llvm/llvm-project/commit/91d765f6ab10974f2c7080c90fe26b21bd7d7cb1.diff
LOG: [FunctionAttrs][Attributor] Update nofree inference (#196266)
This updates nofree inference after the semantics changes in
https://github.com/llvm/llvm-project/pull/195658.
FunctionAttrs currently only supports function-level nofree inference,
so we just need to check for potentially synchronizing instructions.
Attributor also supports argument nofree, in which case we make
additional changes:
* For callsite arguments, in addition to checking nofree, we also need
to check nocapture. If the call itself doesn't free the arg, it may
still capture it and then we may free it via the captured pointer later.
The way this was handled was already incorrect prior to the semantics
changes.
* Reformulate the handling for other instructions in terms of looking
for provenance captures, as that's what the code was essentially doing,
in a crude way. I'm including this to avoid some regressions for cases
where we can no longer infer function nofree, but can still infer
argument nofree.
Added:
Modified:
clang/test/CodeGen/sanitize-metadata-nosanitize.c
llvm/lib/Transforms/IPO/AttributorAttributes.cpp
llvm/lib/Transforms/IPO/FunctionAttrs.cpp
llvm/test/Transforms/Attributor/align-atomic.ll
llvm/test/Transforms/Attributor/align.ll
llvm/test/Transforms/Attributor/liveness.ll
llvm/test/Transforms/Attributor/noalias.ll
llvm/test/Transforms/Attributor/nocapture-1.ll
llvm/test/Transforms/Attributor/nocapture-2.ll
llvm/test/Transforms/Attributor/nofpclass.ll
llvm/test/Transforms/Attributor/nonnull.ll
llvm/test/Transforms/Attributor/nosync.ll
llvm/test/Transforms/Attributor/range.ll
llvm/test/Transforms/Attributor/readattrs.ll
llvm/test/Transforms/Attributor/undefined_behavior.ll
llvm/test/Transforms/Attributor/value-simplify-instances.ll
llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll
llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
llvm/test/Transforms/Attributor/value-simplify.ll
llvm/test/Transforms/FunctionAttrs/atomic.ll
llvm/test/Transforms/FunctionAttrs/nocapture.ll
llvm/test/Transforms/FunctionAttrs/nonnull.ll
llvm/test/Transforms/FunctionAttrs/nosync.ll
llvm/test/Transforms/FunctionAttrs/readattrs.ll
llvm/test/Transforms/FunctionAttrs/writeonly.ll
llvm/test/Transforms/OpenMP/parallel_deletion.ll
Removed:
################################################################################
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/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 69b479fb41ea4..004bd3f741dd8 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -2282,16 +2282,24 @@ struct AANoFreeImpl : public AANoFree {
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
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();
+
return ChangeStatus::UNCHANGED;
}
@@ -2346,27 +2354,42 @@ 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,
+ /*IgnoreSubsumingPositions=*/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/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/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/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll
index 3898c223746b8..a83a3c5f9c6e9 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:%.*]]
diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll
index b7c295ae4179c..415958e151634 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
@@ -970,3 +970,7 @@ l2:
; CGSCC: attributes #[[ATTR14]] = { nofree 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/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index 93690ddef6634..aa0cea33d02d0 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]]
@@ -1553,14 +1553,14 @@ merge:
define void @phi_caller(ptr %p) {
; TUNIT: Function Attrs: nounwind
; TUNIT-LABEL: define {{[^@]+}}@phi_caller
-; TUNIT-SAME: (ptr nofree [[P:%.*]]) #[[ATTR5]] {
+; TUNIT-SAME: (ptr [[P:%.*]]) #[[ATTR5]] {
; 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 nofree [[P:%.*]]) #[[ATTR4]] {
+; CGSCC-SAME: (ptr [[P:%.*]]) #[[ATTR4]] {
; 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
@@ -1593,14 +1593,14 @@ 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-SAME: (ptr [[P:%.*]]) #[[ATTR5]] {
; 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 nofree [[P:%.*]]) #[[ATTR4]] {
+; CGSCC-SAME: (ptr [[P:%.*]]) #[[ATTR4]] {
; 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
@@ -1683,7 +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]] = { nofree willreturn }
+; CGSCC: attributes #[[ATTR21]] = { 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..503ceda37fc26 100644
--- a/llvm/test/Transforms/Attributor/range.ll
+++ b/llvm/test/Transforms/Attributor/range.ll
@@ -1808,7 +1808,7 @@ 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 #[[ATTR6]] = { willreturn }
; CGSCC: attributes #[[ATTR7]] = { nofree nosync willreturn }
;.
; TUNIT: [[RNG0]] = !{i32 0, i32 10}
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-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..caf57217d5114 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
@@ -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]]) #[[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
@@ -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]]) #[[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
@@ -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]]) #[[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
@@ -3673,6 +3673,7 @@ declare void @llvm.assume(i1 noundef)
; 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/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/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..7e9a93cb186ed 100644
--- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -646,13 +646,13 @@ 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
; 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
@@ -663,15 +663,15 @@ 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
; 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
;
@@ -680,13 +680,13 @@ 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
; 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/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/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 75fdb171d94ec..325bc53d2615b 100644
--- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll
+++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
@@ -162,13 +162,13 @@ 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
; 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..9d4eb7faa8256 100644
--- a/llvm/test/Transforms/OpenMP/parallel_deletion.ll
+++ b/llvm/test/Transforms/OpenMP/parallel_deletion.ll
@@ -287,7 +287,7 @@ define void @delete_parallel_2() {
; 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
;
@@ -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
More information about the cfe-commits
mailing list