diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -1608,21 +1608,17 @@ call is dead after inlining. ``nofree`` This function attribute indicates that the function does not, directly or - transitively, call a memory-deallocation function (``free``, for example) - on a memory allocation which existed before the call. + transitively, call a memory-deallocation function (``free``, for example), + or cause such a function to be called by another thread, on a memory + allocation which existed before the call. - As a result, uncaptured pointers that are known to be dereferenceable - prior to a call to a function with the ``nofree`` attribute are still - known to be dereferenceable after the call. The capturing condition is - necessary in environments where the function might communicate the - pointer to another thread which then deallocates the memory. Alternatively, - ``nosync`` would ensure such communication cannot happen and even captured - pointers cannot be freed by the function. + As a result, pointers that are known to be dereferenceable prior to a call + to a function with the ``nofree`` attribute are still known to be + dereferenceable after the call. A ``nofree`` function is explicitly allowed to free memory which it - allocated or (if not ``nosync``) arrange for another thread to free - memory on it's behalf. As a result, perhaps surprisingly, a ``nofree`` - function can return a pointer to a previously deallocated memory object. + allocated. As a result, perhaps surprisingly, a ``nofree`` function can + return a pointer to a previously deallocated memory object. ``noimplicitfloat`` This attributes disables implicit floating-point instructions. ``noinline`` diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -591,6 +591,10 @@ /// higher. bool isAtomic() const; + /// Return true if this instruction has an AtomicOrdering of Release or + /// higher. + bool hasReleaseOrdering() const; + /// Return true if this atomic instruction loads from memory. bool hasAtomicLoad() const; diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -595,6 +595,32 @@ } } +bool Instruction::hasReleaseOrdering() const { + AtomicOrdering Ordering; + switch (getOpcode()) { + case Instruction::Fence: + Ordering = cast(this)->getOrdering(); + break; + case Instruction::AtomicCmpXchg: + // The failure ordering cannot have release ordering. + Ordering = cast(this)->getSuccessOrdering(); + break; + case Instruction::AtomicRMW: + Ordering = cast(this)->getOrdering(); + break; + case Instruction::Store: + Ordering = cast(this)->getOrdering(); + break; + case Instruction::Load: // Loads cannot have release ordering. + default: // Not an atomic instruction + return false; + } + + return Ordering == AtomicOrdering::Release || + Ordering == AtomicOrdering::AcquireRelease || + Ordering == AtomicOrdering::SequentiallyConsistent; +} + bool Instruction::hasAtomicLoad() const { assert(isAtomic()); switch (getOpcode()) { diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -758,7 +758,7 @@ // allocations in existance before the call; a nofree function *is* allowed // to free memory it allocated. const Function *F = A->getParent(); - if (F->doesNotFreeMemory() && F->hasNoSync()) + if (F->doesNotFreeMemory()) return false; } diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -1422,7 +1422,39 @@ return NoFreeAA.isAssumedNoFree(); }; - if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this)) + auto CheckForNoRemoteFree = [&](Instruction &I) { + // If a function F contains a volatile memory operation or a release + // atomic, we must assume that this operation may trigger a free() from + // another thread. This means that F cannot be assumed `nofree`. + // + // The same argument does not apply to acquire atomics: if a release + // atomic in another thread synchronizes-with an acquire atomic A in F in + // such a way that a free(%p) in the other thread happens-before A, then + // %p cannot be dereferenceable before A anyway (dereferences of %p that + // occur just before A would race against or happen-after the free(%p)). + if (I.isVolatile()) { + LLVM_DEBUG(dbgs() << " remote free\n"); + return false; + } + + if (I.hasReleaseOrdering()) { + LLVM_DEBUG(dbgs() << "Release: " << I << '\n'); + + if (auto *FI = dyn_cast(&I)) { + if (FI->getSyncScopeID() == SyncScope::SingleThread) + return true; + } + + LLVM_DEBUG(dbgs() << " remote free\n"); + + return false; + } + + return true; + }; + + if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this) || + !A.checkForAllReadWriteInstructions(CheckForNoRemoteFree, *this)) return indicatePessimisticFixpoint(); return ChangeStatus::UNCHANGED; } diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -1264,19 +1264,29 @@ /// Helper for NoFree inference predicate InstrBreaksAttribute. static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes) { - CallBase *CB = dyn_cast(&I); - if (!CB) - return false; + if (CallBase *CB = dyn_cast(&I)) { + if (CB->hasFnAttr(Attribute::NoFree)) + return false; - if (CB->hasFnAttr(Attribute::NoFree)) - return false; + // Speculatively assume in SCC. + if (Function *Callee = CB->getCalledFunction()) + if (SCCNodes.contains(Callee)) + return false; - // Speculatively assume in SCC. - if (Function *Callee = CB->getCalledFunction()) - if (SCCNodes.contains(Callee)) - return false; + return true; + } - return true; + if (I.isVolatile()) + return true; + + if (I.hasReleaseOrdering()) { + if (auto *FI = dyn_cast(&I)) + return FI->getSyncScopeID() != SyncScope::SingleThread; + + return true; + } + + return false; } /// Attempt to remove convergent function attribute when possible. diff --git a/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll b/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll --- a/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll +++ b/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll @@ -260,9 +260,7 @@ } ; CHECK-LABEL: 'infer_func_attrs2' -; GLOBAL: %p -; POINT-NOT: %p -; FIXME: Can be inferred from attributes +; CHECK: %p define void @infer_func_attrs2(i32* dereferenceable(8) %p) readonly { call void @mayfree() %v = load i32, i32* %p diff --git a/llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll b/llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll --- a/llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-2-inseltpoison.ll @@ -296,16 +296,16 @@ ; The 2nd and 3rd loads may never execute. define void @volatile_is_not_dereferenceable(i16* %ptr) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn +; IS__TUNIT____: Function Attrs: argmemonly nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable -; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-SAME: (i16* align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { ; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0 ; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____: Function Attrs: argmemonly norecurse nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable -; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-SAME: (i16* align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { ; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0 ; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2 ; IS__CGSCC____-NEXT: ret void @@ -849,12 +849,12 @@ ; IS__TUNIT____: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind readonly willreturn } ; IS__TUNIT____: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn } ; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } -; IS__TUNIT____: attributes #[[ATTR3]] = { argmemonly nofree nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR3]] = { argmemonly nounwind willreturn } ; IS__TUNIT____: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind willreturn writeonly } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly nofree norecurse nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly norecurse nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/dereferenceable-2.ll b/llvm/test/Transforms/Attributor/dereferenceable-2.ll --- a/llvm/test/Transforms/Attributor/dereferenceable-2.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-2.ll @@ -296,16 +296,16 @@ ; The 2nd and 3rd loads may never execute. define void @volatile_is_not_dereferenceable(i16* %ptr) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn +; IS__TUNIT____: Function Attrs: argmemonly nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable -; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-SAME: (i16* align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { ; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0 ; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____: Function Attrs: argmemonly norecurse nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable -; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-SAME: (i16* align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] { ; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0 ; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2 ; IS__CGSCC____-NEXT: ret void @@ -849,12 +849,12 @@ ; IS__TUNIT____: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind readonly willreturn } ; IS__TUNIT____: attributes #[[ATTR1]] = { argmemonly nofree nosync nounwind willreturn } ; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } -; IS__TUNIT____: attributes #[[ATTR3]] = { argmemonly nofree nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR3]] = { argmemonly nounwind willreturn } ; IS__TUNIT____: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind willreturn writeonly } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly nofree norecurse nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { argmemonly norecurse nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll --- a/llvm/test/Transforms/Attributor/liveness.ll +++ b/llvm/test/Transforms/Attributor/liveness.ll @@ -71,15 +71,15 @@ } define i32 @volatile_load(i32*) norecurse nounwind uwtable { -; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn +; NOT_CGSCC_NPM: Function Attrs: argmemonly norecurse nounwind uwtable willreturn ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@volatile_load -; NOT_CGSCC_NPM-SAME: (i32* nofree align 4 [[TMP0:%.*]]) #[[ATTR6:[0-9]+]] { +; NOT_CGSCC_NPM-SAME: (i32* align 4 [[TMP0:%.*]]) #[[ATTR6:[0-9]+]] { ; NOT_CGSCC_NPM-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4 ; NOT_CGSCC_NPM-NEXT: ret i32 [[TMP2]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn +; IS__CGSCC____: Function Attrs: argmemonly norecurse nounwind uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_load -; IS__CGSCC____-SAME: (i32* nofree align 4 [[TMP0:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* align 4 [[TMP0:%.*]]) #[[ATTR7:[0-9]+]] { ; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4 ; IS__CGSCC____-NEXT: ret i32 [[TMP2]] ; @@ -2634,7 +2634,7 @@ ; NOT_CGSCC_NPM: attributes #[[ATTR3]] = { noreturn nounwind } ; NOT_CGSCC_NPM: attributes #[[ATTR4]] = { noreturn } ; NOT_CGSCC_NPM: attributes #[[ATTR5]] = { nosync readnone } -; NOT_CGSCC_NPM: attributes #[[ATTR6]] = { argmemonly nofree norecurse nounwind uwtable willreturn } +; NOT_CGSCC_NPM: attributes #[[ATTR6]] = { argmemonly norecurse nounwind uwtable willreturn } ; NOT_CGSCC_NPM: attributes #[[ATTR7]] = { nosync } ; NOT_CGSCC_NPM: attributes #[[ATTR8]] = { argmemonly nofree nosync nounwind willreturn writeonly } ; NOT_CGSCC_NPM: attributes #[[ATTR9]] = { nofree noreturn nosync nounwind readnone } @@ -2652,7 +2652,7 @@ ; IS__CGSCC____: attributes #[[ATTR4]] = { noreturn } ; IS__CGSCC____: attributes #[[ATTR5]] = { nosync readnone } ; IS__CGSCC____: attributes #[[ATTR6]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR7]] = { argmemonly nofree norecurse nounwind uwtable willreturn } +; IS__CGSCC____: attributes #[[ATTR7]] = { argmemonly norecurse nounwind uwtable willreturn } ; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind readnone uwtable willreturn } ; IS__CGSCC____: attributes #[[ATTR9]] = { nosync } ; IS__CGSCC____: attributes #[[ATTR10]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } diff --git a/llvm/test/Transforms/Attributor/nocapture-1.ll b/llvm/test/Transforms/Attributor/nocapture-1.ll --- a/llvm/test/Transforms/Attributor/nocapture-1.ll +++ b/llvm/test/Transforms/Attributor/nocapture-1.ll @@ -54,7 +54,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@c3 ; IS__CGSCC____-SAME: (i32* nofree writeonly [[Q:%.*]]) #[[ATTR1]] { -; IS__CGSCC____-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR17:[0-9]+]] +; IS__CGSCC____-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR18:[0-9]+]] ; IS__CGSCC____-NEXT: ret void ; call void @c2(i32* %q) @@ -221,14 +221,14 @@ ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@c7 ; IS__TUNIT____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] { -; IS__TUNIT____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR15:[0-9]+]] +; IS__TUNIT____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR16:[0-9]+]] ; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1 ; IS__TUNIT____-NEXT: ret i1 [[VAL]] ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@c7 ; IS__CGSCC____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] { -; IS__CGSCC____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR18:[0-9]+]] +; IS__CGSCC____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR19:[0-9]+]] ; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1 ; IS__CGSCC____-NEXT: ret i1 [[VAL]] ; @@ -336,7 +336,7 @@ ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@nc2 ; IS__CGSCC____-SAME: (i32* nocapture nofree [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR5]] { -; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 noundef false) #[[ATTR14:[0-9]+]] +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 noundef false) #[[ATTR15:[0-9]+]] ; IS__CGSCC____-NEXT: ret void ; %1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; [#uses=0] @@ -361,13 +361,13 @@ ; IS__TUNIT____: Function Attrs: argmemonly nounwind ; IS__TUNIT____-LABEL: define {{[^@]+}}@nc4 ; IS__TUNIT____-SAME: (i8* [[P:%.*]]) #[[ATTR6:[0-9]+]] { -; IS__TUNIT____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR16:[0-9]+]] +; IS__TUNIT____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR17:[0-9]+]] ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@nc4 ; IS__CGSCC____-SAME: (i8* [[P:%.*]]) #[[ATTR6:[0-9]+]] { -; IS__CGSCC____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR19:[0-9]+]] +; IS__CGSCC____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR20:[0-9]+]] ; IS__CGSCC____-NEXT: ret void ; call void @external(i8* %p) @@ -571,15 +571,15 @@ } define void @test_atomicrmw(i32* %p) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn +; IS__TUNIT____: Function Attrs: argmemonly nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_atomicrmw -; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR9]] { +; IS__TUNIT____-SAME: (i32* nocapture noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__TUNIT____-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst, align 4 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____: Function Attrs: argmemonly norecurse nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_atomicrmw -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-SAME: (i32* nocapture noundef nonnull dereferenceable(4) [[P:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst, align 4 ; IS__CGSCC____-NEXT: ret void ; @@ -588,17 +588,17 @@ } define void @test_volatile(i32* %x) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn +; IS__TUNIT____: Function Attrs: argmemonly nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test_volatile -; IS__TUNIT____-SAME: (i32* nofree align 4 [[X:%.*]]) #[[ATTR9]] { +; IS__TUNIT____-SAME: (i32* align 4 [[X:%.*]]) #[[ATTR10]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[X]], i64 1 ; IS__TUNIT____-NEXT: store volatile i32 0, i32* [[GEP]], align 4 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____: Function Attrs: argmemonly norecurse nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test_volatile -; IS__CGSCC____-SAME: (i32* nofree align 4 [[X:%.*]]) #[[ATTR9]] { +; IS__CGSCC____-SAME: (i32* align 4 [[X:%.*]]) #[[ATTR10]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[X]], i64 1 ; IS__CGSCC____-NEXT: store volatile i32 0, i32* [[GEP]], align 4 @@ -615,15 +615,15 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureLaunder ; IS__TUNIT____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR5]] { ; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR17:[0-9]+]] +; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR18:[0-9]+]] ; IS__TUNIT____-NEXT: store i8 42, i8* [[B]], align 1 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureLaunder -; IS__CGSCC____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__CGSCC____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR11:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR20:[0-9]+]] +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR21:[0-9]+]] ; IS__CGSCC____-NEXT: store i8 42, i8* [[B]], align 1 ; IS__CGSCC____-NEXT: ret void ; @@ -638,14 +638,14 @@ ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@captureLaunder ; IS__TUNIT____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR5]] { -; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR17]] +; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR18]] ; IS__TUNIT____-NEXT: store i8* [[B]], i8** @g2, align 8 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@captureLaunder -; IS__CGSCC____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR10]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR20]] +; IS__CGSCC____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR11]] { +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR21]] ; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g2, align 8 ; IS__CGSCC____-NEXT: ret void ; @@ -659,15 +659,15 @@ ; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureStrip ; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR1]] { ; IS__TUNIT____-NEXT: entry: -; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18:[0-9]+]] +; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR19:[0-9]+]] ; IS__TUNIT____-NEXT: store i8 42, i8* [[B]], align 1 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureStrip -; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR12:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]] +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: store i8 42, i8* [[B]], align 1 ; IS__CGSCC____-NEXT: ret void ; @@ -682,14 +682,14 @@ ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@captureStrip ; IS__TUNIT____-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR1]] { -; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]] +; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR19]] ; IS__TUNIT____-NEXT: store i8* [[B]], i8** @g3, align 8 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@captureStrip -; IS__CGSCC____-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR11]] { -; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]] +; IS__CGSCC____-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR12]] { +; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR19]] ; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g3, align 8 ; IS__CGSCC____-NEXT: ret void ; @@ -789,14 +789,14 @@ define i1 @captureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) null_pointer_is_valid { ; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp -; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR10:[0-9]+]] { +; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR11:[0-9]+]] { ; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8* ; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null ; IS__TUNIT____-NEXT: ret i1 [[TMP2]] ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp -; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR13:[0-9]+]] { ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8* ; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null ; IS__CGSCC____-NEXT: ret i1 [[TMP2]] @@ -854,13 +854,13 @@ define void @ptr_uses(i8* %ptr, i8* %wptr) { ; IS__TUNIT____: Function Attrs: nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_uses -; IS__TUNIT____-SAME: (i8* [[PTR:%.*]], i8* nocapture noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__TUNIT____-SAME: (i8* [[PTR:%.*]], i8* nocapture noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR13:[0-9]+]] { ; IS__TUNIT____-NEXT: store i8 0, i8* [[WPTR]], align 1 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_uses -; IS__CGSCC____-SAME: (i8* [[PTR:%.*]], i8* nocapture noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR14]] { +; IS__CGSCC____-SAME: (i8* [[PTR:%.*]], i8* nocapture noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR15]] { ; IS__CGSCC____-NEXT: store i8 0, i8* [[WPTR]], align 1 ; IS__CGSCC____-NEXT: ret void ; @@ -884,15 +884,16 @@ ; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly } ; IS__TUNIT____: attributes #[[ATTR8]] = { nofree noreturn nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR9]] = { argmemonly nofree nounwind willreturn } -; IS__TUNIT____: attributes #[[ATTR10]] = { nofree nosync nounwind null_pointer_is_valid readnone willreturn } -; IS__TUNIT____: attributes #[[ATTR11:[0-9]+]] = { nounwind readonly willreturn } -; IS__TUNIT____: attributes #[[ATTR12]] = { nounwind willreturn } -; IS__TUNIT____: attributes #[[ATTR13:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind speculatable willreturn } -; IS__TUNIT____: attributes #[[ATTR14:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } -; IS__TUNIT____: attributes #[[ATTR15]] = { nofree nounwind readnone willreturn } -; IS__TUNIT____: attributes #[[ATTR16]] = { nounwind } -; IS__TUNIT____: attributes #[[ATTR17]] = { willreturn } -; IS__TUNIT____: attributes #[[ATTR18]] = { readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR10]] = { argmemonly nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR11]] = { nofree nosync nounwind null_pointer_is_valid readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR12:[0-9]+]] = { nounwind readonly willreturn } +; IS__TUNIT____: attributes #[[ATTR13]] = { nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR14:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind speculatable willreturn } +; IS__TUNIT____: attributes #[[ATTR15:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } +; IS__TUNIT____: attributes #[[ATTR16]] = { nofree nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR17]] = { nounwind } +; IS__TUNIT____: attributes #[[ATTR18]] = { willreturn } +; IS__TUNIT____: attributes #[[ATTR19]] = { readnone willreturn } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn writeonly } @@ -904,15 +905,16 @@ ; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly } ; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR12]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR13:[0-9]+]] = { nounwind readonly willreturn } -; IS__CGSCC____: attributes #[[ATTR14]] = { nounwind willreturn } -; IS__CGSCC____: attributes #[[ATTR15:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind speculatable willreturn } -; IS__CGSCC____: attributes #[[ATTR16:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } -; IS__CGSCC____: attributes #[[ATTR17]] = { nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR18]] = { readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR19]] = { nounwind } -; IS__CGSCC____: attributes #[[ATTR20]] = { willreturn } +; IS__CGSCC____: attributes #[[ATTR10]] = { argmemonly norecurse nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR12]] = { nofree nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR13]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR14:[0-9]+]] = { nounwind readonly willreturn } +; IS__CGSCC____: attributes #[[ATTR15]] = { nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR16:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind speculatable willreturn } +; IS__CGSCC____: attributes #[[ATTR17:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } +; IS__CGSCC____: attributes #[[ATTR18]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR19]] = { readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR20]] = { nounwind } +; IS__CGSCC____: attributes #[[ATTR21]] = { willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/nofree.ll b/llvm/test/Transforms/Attributor/nofree.ll --- a/llvm/test/Transforms/Attributor/nofree.ll +++ b/llvm/test/Transforms/Attributor/nofree.ll @@ -270,13 +270,13 @@ ; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@call_floor2 ; IS__TUNIT____-SAME: (float [[A:%.*]]) #[[ATTR3]] { -; IS__TUNIT____-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR12:[0-9]+]] +; IS__TUNIT____-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR13:[0-9]+]] ; IS__TUNIT____-NEXT: ret float [[C]] ; ; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@call_floor2 ; IS__CGSCC____-SAME: (float [[A:%.*]]) #[[ATTR7:[0-9]+]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR13:[0-9]+]] +; IS__CGSCC____-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR14:[0-9]+]] ; IS__CGSCC____-NEXT: ret float [[C]] ; %c = tail call float @llvm.floor.f32(float %a) @@ -390,19 +390,17 @@ ret void } -; TEST 16: Use a release atomic (positive) -; TODO: Should this be negative? See discussion on https://reviews.llvm.org/D100676 -; and https://reviews.llvm.org/D101701. +; TEST 16: Use a release atomic (negative) define void @test16(i8* %p) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn +; IS__TUNIT____: Function Attrs: argmemonly nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test16 -; IS__TUNIT____-SAME: (i8* nocapture nofree noundef nonnull dereferenceable(1) [[P:%.*]]) #[[ATTR9]] { +; IS__TUNIT____-SAME: (i8* nocapture noundef nonnull dereferenceable(1) [[P:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__TUNIT____-NEXT: [[X:%.*]] = atomicrmw add i8* [[P]], i8 1 release, align 1 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____: Function Attrs: argmemonly norecurse nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test16 -; IS__CGSCC____-SAME: (i8* nocapture nofree noundef nonnull dereferenceable(1) [[P:%.*]]) #[[ATTR10]] { +; IS__CGSCC____-SAME: (i8* nocapture noundef nonnull dereferenceable(1) [[P:%.*]]) #[[ATTR11:[0-9]+]] { ; IS__CGSCC____-NEXT: [[X:%.*]] = atomicrmw add i8* [[P]], i8 1 release, align 1 ; IS__CGSCC____-NEXT: ret void ; @@ -421,13 +419,13 @@ ; ; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_assume_pos ; IS__TUNIT____-SAME: (i8* nofree [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* nofree [[ARG3:%.*]], i8* [[ARG4:%.*]]) { -; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13:[0-9]+]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] +; IS__TUNIT____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14:[0-9]+]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] ; IS__TUNIT____-NEXT: call void @unknown(i8* nofree [[ARG1]], i8* [[ARG2]], i8* nofree [[ARG3]], i8* [[ARG4]]) ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_assume_pos ; IS__CGSCC____-SAME: (i8* nofree [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* nofree [[ARG3:%.*]], i8* [[ARG4:%.*]]) { -; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR14:[0-9]+]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] +; IS__CGSCC____-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR15:[0-9]+]] [ "nofree"(i8* [[ARG1]]), "nofree"(i8* [[ARG3]]) ] ; IS__CGSCC____-NEXT: call void @unknown(i8* nofree [[ARG1]], i8* [[ARG2]], i8* nofree [[ARG3]], i8* [[ARG4]]) ; IS__CGSCC____-NEXT: ret void ; @@ -517,10 +515,11 @@ ; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nounwind } ; IS__TUNIT____: attributes #[[ATTR8:[0-9]+]] = { nobuiltin nofree nounwind } ; IS__TUNIT____: attributes #[[ATTR9]] = { argmemonly nofree nounwind willreturn } -; IS__TUNIT____: attributes #[[ATTR10:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn } -; IS__TUNIT____: attributes #[[ATTR11:[0-9]+]] = { nounwind willreturn } -; IS__TUNIT____: attributes #[[ATTR12]] = { readnone willreturn } -; IS__TUNIT____: attributes #[[ATTR13]] = { willreturn } +; IS__TUNIT____: attributes #[[ATTR10]] = { argmemonly nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR11:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR12:[0-9]+]] = { nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR13]] = { readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR14]] = { willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { noinline nounwind uwtable } @@ -533,10 +532,11 @@ ; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR9:[0-9]+]] = { nobuiltin nofree nounwind } ; IS__CGSCC_OPM: attributes #[[ATTR10]] = { argmemonly nofree norecurse nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR11:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR12:[0-9]+]] = { nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR14]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR11]] = { argmemonly norecurse nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR12:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR13:[0-9]+]] = { nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR14]] = { readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR15]] = { willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nounwind } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { noinline nounwind uwtable } @@ -549,8 +549,9 @@ ; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree nounwind } ; IS__CGSCC_NPM: attributes #[[ATTR9:[0-9]+]] = { nobuiltin nofree nounwind } ; IS__CGSCC_NPM: attributes #[[ATTR10]] = { argmemonly nofree norecurse nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR12:[0-9]+]] = { nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR13]] = { readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR14]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR11]] = { argmemonly norecurse nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR12:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR13:[0-9]+]] = { nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR14]] = { readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR15]] = { willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/nosync.ll b/llvm/test/Transforms/Attributor/nosync.ll --- a/llvm/test/Transforms/Attributor/nosync.ll +++ b/llvm/test/Transforms/Attributor/nosync.ll @@ -112,9 +112,9 @@ ; } define void @load_release(i32* nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn +; CHECK: Function Attrs: argmemonly norecurse nounwind uwtable willreturn ; CHECK-LABEL: define {{[^@]+}}@load_release -; CHECK-SAME: (i32* nocapture nofree noundef writeonly align 4 [[TMP0:%.*]]) #[[ATTR2]] { +; CHECK-SAME: (i32* nocapture noundef writeonly align 4 [[TMP0:%.*]]) #[[ATTR3:[0-9]+]] { ; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0]] release, align 4 ; CHECK-NEXT: ret void ; @@ -125,9 +125,9 @@ ; TEST 6 - negative volatile, relaxed atomic define void @load_volatile_release(i32* nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn +; CHECK: Function Attrs: argmemonly norecurse nounwind uwtable willreturn ; CHECK-LABEL: define {{[^@]+}}@load_volatile_release -; CHECK-SAME: (i32* nocapture nofree noundef writeonly align 4 [[TMP0:%.*]]) #[[ATTR2]] { +; CHECK-SAME: (i32* nocapture noundef writeonly align 4 [[TMP0:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0]] release, align 4 ; CHECK-NEXT: ret void ; @@ -142,9 +142,9 @@ ; } define void @volatile_store(i32* %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn +; CHECK: Function Attrs: argmemonly norecurse nounwind uwtable willreturn ; CHECK-LABEL: define {{[^@]+}}@volatile_store -; CHECK-SAME: (i32* nofree noundef align 4 [[TMP0:%.*]]) #[[ATTR2]] { +; CHECK-SAME: (i32* noundef align 4 [[TMP0:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: store volatile i32 14, i32* [[TMP0]], align 4 ; CHECK-NEXT: ret void ; @@ -160,9 +160,9 @@ ; } define i32 @volatile_load(i32* %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn +; CHECK: Function Attrs: argmemonly norecurse nounwind uwtable willreturn ; CHECK-LABEL: define {{[^@]+}}@volatile_load -; CHECK-SAME: (i32* nofree align 4 [[TMP0:%.*]]) #[[ATTR2]] { +; CHECK-SAME: (i32* align 4 [[TMP0:%.*]]) #[[ATTR3]] { ; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4 ; CHECK-NEXT: ret i32 [[TMP2]] ; @@ -179,8 +179,8 @@ define void @call_nosync_function() nounwind uwtable noinline { ; CHECK: Function Attrs: noinline nosync nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@call_nosync_function -; CHECK-SAME: () #[[ATTR3:[0-9]+]] { -; CHECK-NEXT: tail call void @nosync_function() #[[ATTR4:[0-9]+]] +; CHECK-SAME: () #[[ATTR4:[0-9]+]] { +; CHECK-NEXT: tail call void @nosync_function() #[[ATTR5:[0-9]+]] ; CHECK-NEXT: ret void ; tail call void @nosync_function() noinline nounwind uwtable @@ -196,8 +196,8 @@ define void @call_might_sync() nounwind uwtable noinline { ; CHECK: Function Attrs: noinline nounwind uwtable ; CHECK-LABEL: define {{[^@]+}}@call_might_sync -; CHECK-SAME: () #[[ATTR4]] { -; CHECK-NEXT: tail call void @might_sync() #[[ATTR4]] +; CHECK-SAME: () #[[ATTR5]] { +; CHECK-NEXT: tail call void @might_sync() #[[ATTR5]] ; CHECK-NEXT: ret void ; tail call void @might_sync() noinline nounwind uwtable @@ -210,12 +210,12 @@ define i32 @scc1(i32* %0) noinline nounwind uwtable { ; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@scc1 -; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] { +; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR6:[0-9]+]] { ; NOT_CGSCC_NPM-NEXT: unreachable ; ; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@scc1 -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] { +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR6:[0-9]+]] { ; IS__CGSCC_NPM-NEXT: unreachable ; tail call void @scc2(i32* %0); @@ -226,12 +226,12 @@ define void @scc2(i32* %0) noinline nounwind uwtable { ; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@scc2 -; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR5]] { +; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR6]] { ; NOT_CGSCC_NPM-NEXT: unreachable ; ; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@scc2 -; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR5]] { +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]]) #[[ATTR6]] { ; IS__CGSCC_NPM-NEXT: unreachable ; tail call i32 @scc1(i32* %0); @@ -258,18 +258,18 @@ %"struct.std::__atomic_base" = type { i8 } define void @foo1(i32* %0, %"struct.std::atomic"* %1) { -; IS__TUNIT____: Function Attrs: nofree nounwind willreturn +; IS__TUNIT____: Function Attrs: nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@foo1 -; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__TUNIT____-SAME: (i32* nocapture noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR7:[0-9]+]] { ; IS__TUNIT____-NEXT: store i32 100, i32* [[TMP0]], align 4 ; IS__TUNIT____-NEXT: fence release ; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0 ; IS__TUNIT____-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nounwind willreturn +; IS__CGSCC____: Function Attrs: norecurse nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1 -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nocapture noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR7:[0-9]+]] { ; IS__CGSCC____-NEXT: store i32 100, i32* [[TMP0]], align 4 ; IS__CGSCC____-NEXT: fence release ; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0 @@ -286,7 +286,7 @@ define void @bar(i32* %0, %"struct.std::atomic"* %1) { ; IS__TUNIT____: Function Attrs: nofree nounwind ; IS__TUNIT____-LABEL: define {{[^@]+}}@bar -; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR8:[0-9]+]] { ; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0 ; IS__TUNIT____-NEXT: br label [[TMP4:%.*]] ; IS__TUNIT____: 4: @@ -300,7 +300,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@bar -; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR8:[0-9]+]] { ; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0 ; IS__CGSCC____-NEXT: br label [[TMP4:%.*]] ; IS__CGSCC____: 4: @@ -330,7 +330,7 @@ define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) { ; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@foo1_singlethread -; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR9:[0-9]+]] { ; IS__TUNIT____-NEXT: store i32 100, i32* [[TMP0]], align 4 ; IS__TUNIT____-NEXT: fence syncscope("singlethread") release ; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0 @@ -339,7 +339,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1_singlethread -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR9:[0-9]+]] { ; IS__CGSCC____-NEXT: store i32 100, i32* [[TMP0]], align 4 ; IS__CGSCC____-NEXT: fence syncscope("singlethread") release ; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0 @@ -356,7 +356,7 @@ define void @bar_singlethread(i32* %0, %"struct.std::atomic"* %1) { ; IS__TUNIT____: Function Attrs: nofree nosync nounwind ; IS__TUNIT____-LABEL: define {{[^@]+}}@bar_singlethread -; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0 ; IS__TUNIT____-NEXT: br label [[TMP4:%.*]] ; IS__TUNIT____: 4: @@ -370,7 +370,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@bar_singlethread -; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR9:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]]) #[[ATTR10:[0-9]+]] { ; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0 ; IS__CGSCC____-NEXT: br label [[TMP4:%.*]] ; IS__CGSCC____: 4: @@ -404,16 +404,16 @@ ; It is odd to add nocapture but a result of the llvm.memcpy nocapture. ; define i32 @memcpy_volatile(i8* %ptr1, i8* %ptr2) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn +; IS__TUNIT____: Function Attrs: argmemonly nosync nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@memcpy_volatile -; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8* nocapture nofree readonly [[PTR2:%.*]]) #[[ATTR10:[0-9]+]] { -; IS__TUNIT____-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[PTR1]], i8* noalias nocapture nofree readonly [[PTR2]], i32 noundef 8, i1 noundef true) #[[ATTR17:[0-9]+]] +; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8* nocapture nofree readonly [[PTR2:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__TUNIT____-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[PTR1]], i8* noalias nocapture nofree readonly [[PTR2]], i32 noundef 8, i1 noundef true) #[[ATTR19:[0-9]+]] ; IS__TUNIT____-NEXT: ret i32 4 ; -; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn +; IS__CGSCC____: Function Attrs: argmemonly nosync nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@memcpy_volatile -; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8* nocapture nofree readonly [[PTR2:%.*]]) #[[ATTR10:[0-9]+]] { -; IS__CGSCC____-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[PTR1]], i8* noalias nocapture nofree readonly [[PTR2]], i32 noundef 8, i1 noundef true) #[[ATTR18:[0-9]+]] +; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8* nocapture nofree readonly [[PTR2:%.*]]) #[[ATTR11:[0-9]+]] { +; IS__CGSCC____-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[PTR1]], i8* noalias nocapture nofree readonly [[PTR2]], i32 noundef 8, i1 noundef true) #[[ATTR20:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 4 ; call void @llvm.memcpy(i8* %ptr1, i8* %ptr2, i32 8, i1 1) @@ -427,14 +427,14 @@ define i32 @memset_non_volatile(i8* %ptr1, i8 %val) { ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@memset_non_volatile -; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8 [[VAL:%.*]]) #[[ATTR11:[0-9]+]] { -; IS__TUNIT____-NEXT: call void @llvm.memset.p0i8.i32(i8* nocapture nofree writeonly [[PTR1]], i8 [[VAL]], i32 noundef 8, i1 noundef false) #[[ATTR18:[0-9]+]] +; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8 [[VAL:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__TUNIT____-NEXT: call void @llvm.memset.p0i8.i32(i8* nocapture nofree writeonly [[PTR1]], i8 [[VAL]], i32 noundef 8, i1 noundef false) #[[ATTR20:[0-9]+]] ; IS__TUNIT____-NEXT: ret i32 4 ; ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@memset_non_volatile -; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8 [[VAL:%.*]]) #[[ATTR11:[0-9]+]] { -; IS__CGSCC____-NEXT: call void @llvm.memset.p0i8.i32(i8* nocapture nofree writeonly [[PTR1]], i8 [[VAL]], i32 noundef 8, i1 noundef false) #[[ATTR19:[0-9]+]] +; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR1:%.*]], i8 [[VAL:%.*]]) #[[ATTR12:[0-9]+]] { +; IS__CGSCC____-NEXT: call void @llvm.memset.p0i8.i32(i8* nocapture nofree writeonly [[PTR1]], i8 [[VAL]], i32 noundef 8, i1 noundef false) #[[ATTR21:[0-9]+]] ; IS__CGSCC____-NEXT: ret i32 4 ; call void @llvm.memset(i8* %ptr1, i8 %val, i32 8, i1 0) @@ -459,7 +459,7 @@ define void @convergent_readnone(){ ; CHECK: Function Attrs: readnone ; CHECK-LABEL: define {{[^@]+}}@convergent_readnone -; CHECK-SAME: () #[[ATTR13:[0-9]+]] { +; CHECK-SAME: () #[[ATTR14:[0-9]+]] { ; CHECK-NEXT: call void @readnone_test() ; CHECK-NEXT: ret void ; @@ -477,7 +477,7 @@ define void @i_totally_sync() { ; CHECK: Function Attrs: nounwind ; CHECK-LABEL: define {{[^@]+}}@i_totally_sync -; CHECK-SAME: () #[[ATTR14:[0-9]+]] { +; CHECK-SAME: () #[[ATTR15:[0-9]+]] { ; CHECK-NEXT: tail call void @llvm.x86.sse2.clflush(i8* noundef nonnull align 4 dereferenceable(4) bitcast (i32* @a to i8*)) ; CHECK-NEXT: ret void ; @@ -492,12 +492,12 @@ define i32 @cos_test(float %x) { ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cos_test -; IS__TUNIT____-SAME: (float [[X:%.*]]) #[[ATTR15:[0-9]+]] { +; IS__TUNIT____-SAME: (float [[X:%.*]]) #[[ATTR16:[0-9]+]] { ; IS__TUNIT____-NEXT: ret i32 4 ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cos_test -; IS__CGSCC____-SAME: (float [[X:%.*]]) #[[ATTR15:[0-9]+]] { +; IS__CGSCC____-SAME: (float [[X:%.*]]) #[[ATTR16:[0-9]+]] { ; IS__CGSCC____-NEXT: ret i32 4 ; call float @llvm.cos(float %x) @@ -507,14 +507,14 @@ define float @cos_test2(float %x) { ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cos_test2 -; IS__TUNIT____-SAME: (float [[X:%.*]]) #[[ATTR15]] { -; IS__TUNIT____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR19:[0-9]+]] +; IS__TUNIT____-SAME: (float [[X:%.*]]) #[[ATTR16]] { +; IS__TUNIT____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR21:[0-9]+]] ; IS__TUNIT____-NEXT: ret float [[C]] ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cos_test2 -; IS__CGSCC____-SAME: (float [[X:%.*]]) #[[ATTR16:[0-9]+]] { -; IS__CGSCC____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR20:[0-9]+]] +; IS__CGSCC____-SAME: (float [[X:%.*]]) #[[ATTR17:[0-9]+]] { +; IS__CGSCC____-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]]) #[[ATTR22:[0-9]+]] ; IS__CGSCC____-NEXT: ret float [[C]] ; %c = call float @llvm.cos(float %x) @@ -524,65 +524,71 @@ ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind optsize readnone ssp uwtable willreturn } ; IS__TUNIT____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind uwtable willreturn } ; IS__TUNIT____: attributes #[[ATTR2]] = { argmemonly nofree norecurse nounwind uwtable willreturn } -; IS__TUNIT____: attributes #[[ATTR3]] = { noinline nosync nounwind uwtable } -; IS__TUNIT____: attributes #[[ATTR4]] = { noinline nounwind uwtable } -; IS__TUNIT____: attributes #[[ATTR5]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn } -; IS__TUNIT____: attributes #[[ATTR6]] = { nofree nounwind willreturn } -; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nounwind } -; IS__TUNIT____: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn } -; IS__TUNIT____: attributes #[[ATTR9]] = { nofree nosync nounwind } -; IS__TUNIT____: attributes #[[ATTR10]] = { argmemonly nofree nosync nounwind willreturn } -; IS__TUNIT____: attributes #[[ATTR11]] = { argmemonly nofree nosync nounwind willreturn writeonly } -; IS__TUNIT____: attributes #[[ATTR12:[0-9]+]] = { convergent readnone } -; IS__TUNIT____: attributes #[[ATTR13]] = { readnone } -; IS__TUNIT____: attributes #[[ATTR14]] = { nounwind } -; IS__TUNIT____: attributes #[[ATTR15]] = { nofree nosync nounwind readnone willreturn } -; IS__TUNIT____: attributes #[[ATTR16:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } -; IS__TUNIT____: attributes #[[ATTR17]] = { willreturn } -; IS__TUNIT____: attributes #[[ATTR18]] = { willreturn writeonly } -; IS__TUNIT____: attributes #[[ATTR19]] = { readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR3]] = { argmemonly norecurse nounwind uwtable willreturn } +; IS__TUNIT____: attributes #[[ATTR4]] = { noinline nosync nounwind uwtable } +; IS__TUNIT____: attributes #[[ATTR5]] = { noinline nounwind uwtable } +; IS__TUNIT____: attributes #[[ATTR6]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn } +; IS__TUNIT____: attributes #[[ATTR7]] = { nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR8]] = { nofree nounwind } +; IS__TUNIT____: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR10]] = { nofree nosync nounwind } +; IS__TUNIT____: attributes #[[ATTR11]] = { argmemonly nosync nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR12]] = { argmemonly nofree nosync nounwind willreturn writeonly } +; IS__TUNIT____: attributes #[[ATTR13:[0-9]+]] = { convergent readnone } +; IS__TUNIT____: attributes #[[ATTR14]] = { readnone } +; IS__TUNIT____: attributes #[[ATTR15]] = { nounwind } +; IS__TUNIT____: attributes #[[ATTR16]] = { nofree nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR17:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR18:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } +; IS__TUNIT____: attributes #[[ATTR19]] = { willreturn } +; IS__TUNIT____: attributes #[[ATTR20]] = { willreturn writeonly } +; IS__TUNIT____: attributes #[[ATTR21]] = { readnone willreturn } ;. ; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind uwtable willreturn } ; IS__CGSCC_OPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nounwind uwtable willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR3]] = { noinline nosync nounwind uwtable } -; IS__CGSCC_OPM: attributes #[[ATTR4]] = { noinline nounwind uwtable } -; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nofree norecurse nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nofree norecurse nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR10]] = { argmemonly nofree nosync nounwind willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR11]] = { argmemonly nofree nosync nounwind willreturn writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR12:[0-9]+]] = { convergent readnone } -; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readnone } -; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nounwind } -; IS__CGSCC_OPM: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR17:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR18]] = { willreturn } -; IS__CGSCC_OPM: attributes #[[ATTR19]] = { willreturn writeonly } -; IS__CGSCC_OPM: attributes #[[ATTR20]] = { readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR3]] = { argmemonly norecurse nounwind uwtable willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR4]] = { noinline nosync nounwind uwtable } +; IS__CGSCC_OPM: attributes #[[ATTR5]] = { noinline nounwind uwtable } +; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR7]] = { norecurse nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree norecurse nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR11]] = { argmemonly nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR12]] = { argmemonly nofree nosync nounwind willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR13:[0-9]+]] = { convergent readnone } +; IS__CGSCC_OPM: attributes #[[ATTR14]] = { readnone } +; IS__CGSCC_OPM: attributes #[[ATTR15]] = { nounwind } +; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR17]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR18:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR19:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR20]] = { willreturn } +; IS__CGSCC_OPM: attributes #[[ATTR21]] = { willreturn writeonly } +; IS__CGSCC_OPM: attributes #[[ATTR22]] = { readnone willreturn } ;. ; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind uwtable willreturn } ; IS__CGSCC_NPM: attributes #[[ATTR2]] = { argmemonly nofree norecurse nounwind uwtable willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR3]] = { noinline nosync nounwind uwtable } -; IS__CGSCC_NPM: attributes #[[ATTR4]] = { noinline nounwind uwtable } -; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nofree norecurse nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree norecurse nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR10]] = { argmemonly nofree nosync nounwind willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR11]] = { argmemonly nofree nosync nounwind willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR12:[0-9]+]] = { convergent readnone } -; IS__CGSCC_NPM: attributes #[[ATTR13]] = { readnone } -; IS__CGSCC_NPM: attributes #[[ATTR14]] = { nounwind } -; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR16]] = { nofree nosync nounwind readnone willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR17:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR18]] = { willreturn } -; IS__CGSCC_NPM: attributes #[[ATTR19]] = { willreturn writeonly } -; IS__CGSCC_NPM: attributes #[[ATTR20]] = { readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR3]] = { argmemonly norecurse nounwind uwtable willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR4]] = { noinline nosync nounwind uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR5]] = { noinline nounwind uwtable } +; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR7]] = { norecurse nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR11]] = { argmemonly nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR12]] = { argmemonly nofree nosync nounwind willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR13:[0-9]+]] = { convergent readnone } +; IS__CGSCC_NPM: attributes #[[ATTR14]] = { readnone } +; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nounwind } +; IS__CGSCC_NPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR17]] = { nofree nosync nounwind readnone willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR18:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR19:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR20]] = { willreturn } +; IS__CGSCC_NPM: attributes #[[ATTR21]] = { willreturn writeonly } +; IS__CGSCC_NPM: attributes #[[ATTR22]] = { readnone willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -241,15 +241,15 @@ } define i32 @volatile_load(i32* %p) { -; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn +; IS__TUNIT____: Function Attrs: argmemonly nounwind willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_load -; IS__TUNIT____-SAME: (i32* nofree noundef align 4 [[P:%.*]]) #[[ATTR7:[0-9]+]] { +; IS__TUNIT____-SAME: (i32* noundef align 4 [[P:%.*]]) #[[ATTR7:[0-9]+]] { ; IS__TUNIT____-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4 ; IS__TUNIT____-NEXT: ret i32 [[LOAD]] ; -; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn +; IS__CGSCC____: Function Attrs: argmemonly norecurse nounwind willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_load -; IS__CGSCC____-SAME: (i32* nofree noundef align 4 [[P:%.*]]) #[[ATTR8:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* noundef align 4 [[P:%.*]]) #[[ATTR8:[0-9]+]] { ; IS__CGSCC____-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4 ; IS__CGSCC____-NEXT: ret i32 [[LOAD]] ; @@ -500,7 +500,7 @@ ; IS__TUNIT____: attributes #[[ATTR4]] = { nofree nosync nounwind readonly willreturn } ; IS__TUNIT____: attributes #[[ATTR5]] = { argmemonly nounwind readonly } ; IS__TUNIT____: attributes #[[ATTR6]] = { argmemonly nounwind } -; IS__TUNIT____: attributes #[[ATTR7]] = { argmemonly nofree nounwind willreturn } +; IS__TUNIT____: attributes #[[ATTR7]] = { argmemonly nounwind willreturn } ; IS__TUNIT____: attributes #[[ATTR8]] = { readnone } ; IS__TUNIT____: attributes #[[ATTR9]] = { nounwind readonly } ; IS__TUNIT____: attributes #[[ATTR10]] = { willreturn writeonly } @@ -515,7 +515,7 @@ ; IS__CGSCC____: attributes #[[ATTR5]] = { nofree nosync nounwind readonly willreturn } ; IS__CGSCC____: attributes #[[ATTR6]] = { argmemonly nounwind readonly } ; IS__CGSCC____: attributes #[[ATTR7]] = { argmemonly nounwind } -; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nounwind willreturn } +; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly norecurse nounwind willreturn } ; IS__CGSCC____: attributes #[[ATTR9]] = { readnone } ; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind readonly } ; IS__CGSCC____: attributes #[[ATTR11]] = { readnone willreturn } diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll --- a/llvm/test/Transforms/Attributor/undefined_behavior.ll +++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -276,14 +276,14 @@ ; -- AtomicCmpXchg tests -- define void @atomiccmpxchg_wholly_unreachable() { -; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn +; IS__TUNIT____: Function Attrs: nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable -; IS__TUNIT____-SAME: () #[[ATTR3]] { +; IS__TUNIT____-SAME: () #[[ATTR5:[0-9]+]] { ; IS__TUNIT____-NEXT: unreachable ; -; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable -; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-SAME: () #[[ATTR5:[0-9]+]] { ; IS__CGSCC____-NEXT: unreachable ; %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic @@ -291,18 +291,18 @@ } define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) { -; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn +; IS__TUNIT____: Function Attrs: nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable -; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR5]] { ; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: e: ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable -; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR5]] { ; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable @@ -318,15 +318,15 @@ } define void @atomiccmpxchg_null_pointer_is_defined() null_pointer_is_valid { -; IS__TUNIT____: Function Attrs: nofree nounwind null_pointer_is_valid willreturn +; IS__TUNIT____: Function Attrs: nounwind null_pointer_is_valid willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined -; IS__TUNIT____-SAME: () #[[ATTR4]] { +; IS__TUNIT____-SAME: () #[[ATTR6:[0-9]+]] { ; IS__TUNIT____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic, align 4 ; IS__TUNIT____-NEXT: ret void ; -; IS__CGSCC____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn +; IS__CGSCC____: Function Attrs: norecurse nounwind null_pointer_is_valid willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined -; IS__CGSCC____-SAME: () #[[ATTR4]] { +; IS__CGSCC____-SAME: () #[[ATTR6:[0-9]+]] { ; IS__CGSCC____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic, align 4 ; IS__CGSCC____-NEXT: ret void ; @@ -338,14 +338,14 @@ ; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_propagated( ; ATTRIBUTOR-NEXT: unreachable ; -; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn +; IS__TUNIT____: Function Attrs: nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated -; IS__TUNIT____-SAME: () #[[ATTR3]] { +; IS__TUNIT____-SAME: () #[[ATTR5]] { ; IS__TUNIT____-NEXT: unreachable ; -; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____: Function Attrs: norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated -; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-SAME: () #[[ATTR5]] { ; IS__CGSCC____-NEXT: unreachable ; %ptr = call i32* @ret_null() @@ -360,7 +360,7 @@ define i32 @cond_br_on_undef() { ; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef -; IS__TUNIT____-SAME: () #[[ATTR5:[0-9]+]] { +; IS__TUNIT____-SAME: () #[[ATTR7:[0-9]+]] { ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable @@ -369,7 +369,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef -; IS__CGSCC____-SAME: () #[[ATTR5:[0-9]+]] { +; IS__CGSCC____-SAME: () #[[ATTR7:[0-9]+]] { ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable @@ -441,7 +441,7 @@ define void @cond_br_on_undef_interproc() { ; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc -; IS__TUNIT____-SAME: () #[[ATTR5]] { +; IS__TUNIT____-SAME: () #[[ATTR7]] { ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable @@ -450,7 +450,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc -; IS__CGSCC____-SAME: () #[[ATTR5]] { +; IS__CGSCC____-SAME: () #[[ATTR7]] { ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable @@ -495,7 +495,7 @@ define void @cond_br_on_undef_interproc2() { ; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 -; IS__TUNIT____-SAME: () #[[ATTR5]] { +; IS__TUNIT____-SAME: () #[[ATTR7]] { ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable @@ -504,7 +504,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 -; IS__CGSCC____-SAME: () #[[ATTR5]] { +; IS__CGSCC____-SAME: () #[[ATTR7]] { ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable @@ -631,13 +631,13 @@ define void @arg_nonnull_1(i32* nonnull %a) { ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_1 -; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR8:[0-9]+]] { ; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_1 -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR8:[0-9]+]] { ; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__CGSCC____-NEXT: ret void ; @@ -648,13 +648,13 @@ define void @arg_nonnull_1_noundef_1(i32* nonnull noundef %a) { ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 -; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6]] { +; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR8]] { ; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 -; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR8]] { ; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 ; IS__CGSCC____-NEXT: ret void ; @@ -665,7 +665,7 @@ define void @arg_nonnull_12(i32* nonnull %a, i32* nonnull %b, i32* %c) { ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_12 -; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR8]] { ; IS__TUNIT____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null ; IS__TUNIT____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: @@ -679,7 +679,7 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_12 -; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR8]] { ; IS__CGSCC____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null ; IS__CGSCC____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: @@ -706,7 +706,7 @@ define void @arg_nonnull_12_noundef_2(i32* nonnull %a, i32* noundef nonnull %b, i32* %c) { ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 -; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR8]] { ; IS__TUNIT____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null ; IS__TUNIT____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: @@ -720,7 +720,7 @@ ; ; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 -; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR8]] { ; IS__CGSCC____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null ; IS__CGSCC____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: @@ -818,8 +818,8 @@ ; IS__TUNIT____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7:[0-9]+]] -; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 536870912 null) #[[ATTR7]] +; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR9:[0-9]+]] +; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 536870912 null) #[[ATTR9]] ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: f: ; IS__TUNIT____-NEXT: unreachable @@ -832,8 +832,8 @@ ; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7:[0-9]+]] -; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 536870912 null) #[[ATTR7]] +; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR9:[0-9]+]] +; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 536870912 null) #[[ATTR9]] ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable @@ -865,8 +865,8 @@ ; IS__TUNIT____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: -; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7]] -; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 536870912 null) #[[ATTR7]] +; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR9]] +; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 536870912 null) #[[ATTR9]] ; IS__TUNIT____-NEXT: unreachable ; IS__TUNIT____: f: ; IS__TUNIT____-NEXT: unreachable @@ -879,8 +879,8 @@ ; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: -; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7]] -; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 536870912 null) #[[ATTR7]] +; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR9]] +; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 536870912 null) #[[ATTR9]] ; IS__CGSCC____-NEXT: unreachable ; IS__CGSCC____: f: ; IS__CGSCC____-NEXT: unreachable @@ -1131,16 +1131,20 @@ ; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind null_pointer_is_valid willreturn writeonly } ; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR4]] = { nofree nounwind null_pointer_is_valid willreturn } -; IS__TUNIT____: attributes #[[ATTR5]] = { nofree noreturn nosync nounwind readnone willreturn } -; IS__TUNIT____: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind willreturn writeonly } -; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn writeonly } +; IS__TUNIT____: attributes #[[ATTR5]] = { nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR6]] = { nounwind null_pointer_is_valid willreturn } +; IS__TUNIT____: attributes #[[ATTR7]] = { nofree noreturn nosync nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR8]] = { argmemonly nofree nosync nounwind willreturn writeonly } +; IS__TUNIT____: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn writeonly } ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR4]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } -; IS__CGSCC____: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR7]] = { nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR5]] = { norecurse nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR6]] = { norecurse nounwind null_pointer_is_valid willreturn } +; IS__CGSCC____: attributes #[[ATTR7]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } +; IS__CGSCC____: attributes #[[ATTR9]] = { nounwind willreturn writeonly } ;. diff --git a/llvm/test/Transforms/FunctionAttrs/atomic.ll b/llvm/test/Transforms/FunctionAttrs/atomic.ll --- a/llvm/test/Transforms/FunctionAttrs/atomic.ll +++ b/llvm/test/Transforms/FunctionAttrs/atomic.ll @@ -20,10 +20,9 @@ ret i32 %r } -; TODO: Should a function with a Release store be nofree? See discussion on -; https://reviews.llvm.org/D100676 and https://reviews.llvm.org/D101701. +; A function with a Release store is not nofree. define void @test3(i32* %x) uwtable ssp { -; CHECK: define void @test3(i32* nocapture %x) #1 { +; CHECK: define void @test3(i32* nocapture %x) #2 { entry: store atomic i32 0, i32* %x seq_cst, align 4 ret void @@ -31,3 +30,4 @@ ; CHECK: attributes #0 = { nofree norecurse nosync nounwind readnone ssp uwtable willreturn mustprogress } ; CHECK: attributes #1 = { nofree norecurse nounwind ssp uwtable willreturn mustprogress } +; CHECK: attributes #2 = { norecurse nounwind ssp uwtable willreturn mustprogress } diff --git a/llvm/test/Transforms/FunctionAttrs/nosync.ll b/llvm/test/Transforms/FunctionAttrs/nosync.ll --- a/llvm/test/Transforms/FunctionAttrs/nosync.ll +++ b/llvm/test/Transforms/FunctionAttrs/nosync.ll @@ -49,7 +49,7 @@ ; negative case - explicit sync define void @test5(i8* %p) { -; CHECK: Function Attrs: nofree norecurse nounwind willreturn mustprogress +; CHECK: Function Attrs: norecurse nounwind willreturn mustprogress ; CHECK-LABEL: @test5( ; CHECK-NEXT: store atomic i8 0, i8* [[P:%.*]] seq_cst, align 1 ; CHECK-NEXT: ret void @@ -71,7 +71,7 @@ ; negative case - explicit sync define void @test7(i8* %p) { -; CHECK: Function Attrs: nofree norecurse nounwind willreturn mustprogress +; CHECK: Function Attrs: norecurse nounwind willreturn mustprogress ; CHECK-LABEL: @test7( ; CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add i8* [[P:%.*]], i8 0 seq_cst, align 1 ; CHECK-NEXT: ret void @@ -82,7 +82,7 @@ ; negative case - explicit sync define void @test8(i8* %p) { -; CHECK: Function Attrs: nofree norecurse nounwind willreturn mustprogress +; CHECK: Function Attrs: norecurse nounwind willreturn mustprogress ; CHECK-LABEL: @test8( ; CHECK-NEXT: fence seq_cst ; CHECK-NEXT: ret void @@ -161,7 +161,7 @@ ; negative, should not deduce nosync ; atomic load with release ordering define void @load_release(i32* nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: nofree norecurse nounwind uwtable willreturn mustprogress +; CHECK: Function Attrs: norecurse nounwind uwtable willreturn mustprogress ; CHECK-LABEL: @load_release( ; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0:%.*]] release, align 4 ; CHECK-NEXT: ret void @@ -172,7 +172,7 @@ ; negative volatile, relaxed atomic define void @load_volatile_release(i32* nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: nofree norecurse nounwind uwtable willreturn mustprogress +; CHECK: Function Attrs: norecurse nounwind uwtable willreturn mustprogress ; CHECK-LABEL: @load_volatile_release( ; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0:%.*]] release, align 4 ; CHECK-NEXT: ret void @@ -183,7 +183,7 @@ ; volatile store. define void @volatile_store(i32* %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: nofree norecurse nounwind uwtable willreturn mustprogress +; CHECK: Function Attrs: norecurse nounwind uwtable willreturn mustprogress ; CHECK-LABEL: @volatile_store( ; CHECK-NEXT: store volatile i32 14, i32* [[TMP0:%.*]], align 4 ; CHECK-NEXT: ret void @@ -195,7 +195,7 @@ ; negative, should not deduce nosync ; volatile load. define i32 @volatile_load(i32* %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: nofree norecurse nounwind uwtable willreturn mustprogress +; CHECK: Function Attrs: norecurse nounwind uwtable willreturn mustprogress ; CHECK-LABEL: @volatile_load( ; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0:%.*]], align 4 ; CHECK-NEXT: ret i32 [[TMP2]] @@ -211,7 +211,7 @@ define void @call_nosync_function() nounwind uwtable noinline { ; CHECK: Function Attrs: noinline nosync nounwind uwtable ; CHECK-LABEL: @call_nosync_function( -; CHECK-NEXT: tail call void @nosync_function() #[[ATTR8:[0-9]+]] +; CHECK-NEXT: tail call void @nosync_function() #[[ATTR10:[0-9]+]] ; CHECK-NEXT: ret void ; tail call void @nosync_function() noinline nounwind uwtable @@ -225,7 +225,7 @@ define void @call_might_sync() nounwind uwtable noinline { ; CHECK: Function Attrs: noinline nounwind uwtable ; CHECK-LABEL: @call_might_sync( -; CHECK-NEXT: tail call void @might_sync() #[[ATTR8]] +; CHECK-NEXT: tail call void @might_sync() #[[ATTR10]] ; CHECK-NEXT: ret void ; tail call void @might_sync() noinline nounwind uwtable