llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-llvm-transforms Author: Nikita Popov (nikic) <details> <summary>Changes</summary> 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. --- Patch is 194.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/196266.diff 31 Files Affected: - (modified) clang/test/CodeGen/sanitize-metadata-nosanitize.c (+7-7) - (modified) llvm/lib/Transforms/IPO/AttributorAttributes.cpp (+35-11) - (modified) llvm/lib/Transforms/IPO/FunctionAttrs.cpp (+5-2) - (modified) llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll (+2-2) - (modified) llvm/test/Transforms/Attributor/align-atomic.ll (+2-2) - (modified) llvm/test/Transforms/Attributor/align.ll (+14-14) - (modified) llvm/test/Transforms/Attributor/dereferenceable-1.ll (+2-2) - (modified) llvm/test/Transforms/Attributor/liveness.ll (+61-74) - (modified) llvm/test/Transforms/Attributor/misc.ll (+2-2) - (modified) llvm/test/Transforms/Attributor/noalias.ll (+9-5) - (modified) llvm/test/Transforms/Attributor/nocapture-1.ll (+14-14) - (modified) llvm/test/Transforms/Attributor/nocapture-2.ll (+2-2) - (modified) llvm/test/Transforms/Attributor/nofpclass.ll (+87-44) - (modified) llvm/test/Transforms/Attributor/nofree.ll (+25-27) - (modified) llvm/test/Transforms/Attributor/nonnull.ll (+16-14) - (modified) llvm/test/Transforms/Attributor/nosync.ll (+15-15) - (modified) llvm/test/Transforms/Attributor/range.ll (+57-55) - (modified) llvm/test/Transforms/Attributor/readattrs.ll (+5-5) - (modified) llvm/test/Transforms/Attributor/undefined_behavior.ll (+22-22) - (modified) llvm/test/Transforms/Attributor/value-simplify-assume.ll (+54-52) - (modified) llvm/test/Transforms/Attributor/value-simplify-instances.ll (+27-23) - (modified) llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll (+2-2) - (modified) llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll (+56-53) - (modified) llvm/test/Transforms/Attributor/value-simplify.ll (+15-14) - (modified) llvm/test/Transforms/FunctionAttrs/atomic.ll (+1-1) - (modified) llvm/test/Transforms/FunctionAttrs/nocapture.ll (+7-7) - (modified) llvm/test/Transforms/FunctionAttrs/nonnull.ll (+6-12) - (modified) llvm/test/Transforms/FunctionAttrs/nosync.ll (+9-9) - (modified) llvm/test/Transforms/FunctionAttrs/readattrs.ll (+12-12) - (modified) llvm/test/Transforms/FunctionAttrs/writeonly.ll (+2-2) - (modified) llvm/test/Transforms/OpenMP/parallel_deletion.ll (+5-5) ``````````diff 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 7c50b9faf3c80..3f33a26751726 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -2281,6 +2281,15 @@ struct AANoFreeImpl : public AANoFree { /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { + // Make sure that synchronization cannot establish happens-before with a + // free on another thread. + const IRPosition &IRP = getIRPosition(); + bool IsKnown; + if (!AA::hasAssumedIRAttr<Attribute::NoSync>( + A, this, IRPosition::function_scope(IRP), DepClassTy::REQUIRED, + IsKnown)) + return indicatePessimisticFixpoint(); + auto CheckForNoFree = [&](Instruction &I) { bool IsKnown; return AA::hasAssumedIRAttr<Attribute::NoFree>( @@ -2292,6 +2301,7 @@ struct AANoFreeImpl : public AANoFree { if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this, UsedAssumedInformation)) return indicatePessimisticFixpoint(); + return ChangeStatus::UNCHANGED; } @@ -2346,27 +2356,41 @@ struct AANoFreeFloating : AANoFreeImpl { return true; unsigned ArgNo = CB->getArgOperandNo(&U); + // Even if the argument is nofree, we still need to check for nocapture, + // as the call may capture the argument without freeing it, and the + // captured argument is freed later. bool IsKnown; - return AA::hasAssumedIRAttr<Attribute::NoFree>( - A, this, IRPosition::callsite_argument(*CB, ArgNo), - DepClassTy::REQUIRED, IsKnown); + if (!AA::hasAssumedIRAttr<Attribute::NoFree>( + A, this, IRPosition::callsite_argument(*CB, ArgNo), + DepClassTy::REQUIRED, IsKnown)) + return false; + + const AANoCapture *NoCaptureAA = nullptr; + if (!AA::hasAssumedIRAttr<Attribute::Captures>( + A, this, IRPosition::callsite_argument(*CB, ArgNo), + DepClassTy::REQUIRED, IsKnown, false, &NoCaptureAA)) { + if (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()) { + Follow = true; + return true; + } + return false; + } + + return true; } - if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) || - isa<SelectInst>(UserI)) { + UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr); + if (!capturesAnyProvenance(CI)) + return true; + if (capturesAnyProvenance(CI.ResultCC)) { Follow = true; return true; } - if (isa<LoadInst>(UserI)) - return true; - - if (isa<StoreInst>(UserI)) - return U.getOperandNo() == StoreInst::getPointerOperandIndex(); if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition()) return true; - // Unknown user. + // Capturing user. return false; }; if (!A.checkForAllUses(Pred, *this, AssociatedValue)) diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index c6113fbb96b3f..06b1be0ec902d 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/ArgumentPromotion/X86/thiscall.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll index 4795b424b0d2d..139f42c6d36e1 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll @@ -59,8 +59,8 @@ declare ptr @llvm.stacksave() declare void @llvm.stackrestore(ptr) ;. ; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } -; TUNIT: attributes #[[ATTR1]] = { nofree willreturn } +; TUNIT: attributes #[[ATTR1]] = { willreturn } ;. ; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } -; CGSCC: attributes #[[ATTR1]] = { nofree willreturn } +; CGSCC: attributes #[[ATTR1]] = { willreturn } ;. diff --git a/llvm/test/Transforms/Attributor/align-atomic.ll b/llvm/test/Transforms/Attributor/align-atomic.ll index 0b363741cc168..3c3db2ce27ca4 100644 --- a/llvm/test/Transforms/Attributor/align-atomic.ll +++ b/llvm/test/Transforms/Attributor/align-atomic.ll @@ -26,7 +26,7 @@ define i32 @atomicrmw_add_propagate(ptr align 8 %ptr, i32 %val) { ; Should increase alignment to 8, not 16. define ptr @atomicrmw_non_ptr_op_no_propagate(ptr %ptr, ptr align 16 %val) { ; CHECK-LABEL: define ptr @atomicrmw_non_ptr_op_no_propagate( -; CHECK-SAME: ptr nofree noundef nonnull align 2 captures(none) dereferenceable(8) [[PTR:%.*]], ptr nofree align 16 [[VAL:%.*]]) #[[ATTR0]] { +; CHECK-SAME: ptr nofree noundef nonnull align 2 captures(none) dereferenceable(8) [[PTR:%.*]], ptr align 16 [[VAL:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[RESULT:%.*]] = atomicrmw xchg ptr [[PTR]], ptr [[VAL]] seq_cst, align 2 ; CHECK-NEXT: ret ptr [[RESULT]] ; @@ -49,7 +49,7 @@ define i32 @cmpxchg_propagate(ptr align 8 %ptr, i32 %cmp, i32 %val) { ; Should not increase alignment define ptr @cmpxchg_no_propagate(ptr %ptr, ptr align 16 %cmp, ptr align 32 %val) { ; CHECK-LABEL: define ptr @cmpxchg_no_propagate( -; CHECK-SAME: ptr nofree noundef nonnull align 2 captures(none) dereferenceable(8) [[PTR:%.*]], ptr nofree align 16 [[CMP:%.*]], ptr nofree align 32 [[VAL:%.*]]) #[[ATTR0]] { +; CHECK-SAME: ptr nofree noundef nonnull align 2 captures(none) dereferenceable(8) [[PTR:%.*]], ptr align 16 [[CMP:%.*]], ptr align 32 [[VAL:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[PAIR:%.*]] = cmpxchg ptr [[PTR]], ptr [[CMP]], ptr [[VAL]] seq_cst monotonic, align 2 ; CHECK-NEXT: [[RESULT:%.*]] = extractvalue { ptr, i1 } [[PAIR]], 0 ; CHECK-NEXT: ret ptr [[RESULT]] diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll index 586aecb7cae1f..904233408c144 100644 --- a/llvm/test/Transforms/Attributor/align.ll +++ b/llvm/test/Transforms/Attributor/align.ll @@ -1115,7 +1115,7 @@ entry: } define i64 @infer_align_atomicrmw(ptr align 4 %p) { -; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@infer_align_atomicrmw ; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]]) #[[ATTR12:[0-9]+]] { ; TUNIT-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1 @@ -1123,7 +1123,7 @@ define i64 @infer_align_atomicrmw(ptr align 4 %p) { ; TUNIT-NEXT: [[RET:%.*]] = atomicrmw add ptr [[ARRAYIDX1]], i64 4 seq_cst, align 16 ; TUNIT-NEXT: ret i64 [[RET]] ; -; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@infer_align_atomicrmw ; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]]) #[[ATTR14:[0-9]+]] { ; CGSCC-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1 @@ -1138,17 +1138,17 @@ define i64 @infer_align_atomicrmw(ptr align 4 %p) { } define ptr @infer_align_atomicrmw_ptr(ptr align 4 %p, ptr %val) { -; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@infer_align_atomicrmw_ptr -; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr nofree [[VAL:%.*]]) #[[ATTR12]] { +; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr [[VAL:%.*]]) #[[ATTR12]] { ; TUNIT-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1 ; TUNIT-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3 ; TUNIT-NEXT: [[RET:%.*]] = atomicrmw xchg ptr [[ARRAYIDX1]], ptr [[VAL]] seq_cst, align 16 ; TUNIT-NEXT: ret ptr [[RET]] ; -; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@infer_align_atomicrmw_ptr -; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr nofree [[VAL:%.*]]) #[[ATTR14]] { +; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr [[VAL:%.*]]) #[[ATTR14]] { ; CGSCC-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1 ; CGSCC-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3 ; CGSCC-NEXT: [[RET:%.*]] = atomicrmw xchg ptr [[ARRAYIDX1]], ptr [[VAL]] seq_cst, align 16 @@ -1161,7 +1161,7 @@ define ptr @infer_align_atomicrmw_ptr(ptr align 4 %p, ptr %val) { } define i64 @infer_align_cmpxchg(ptr align 4 %p) { -; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@infer_align_cmpxchg ; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]]) #[[ATTR12]] { ; TUNIT-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1 @@ -1170,7 +1170,7 @@ define i64 @infer_align_cmpxchg(ptr align 4 %p) { ; TUNIT-NEXT: [[RET:%.*]] = extractvalue { i64, i1 } [[CMPX]], 0 ; TUNIT-NEXT: ret i64 [[RET]] ; -; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@infer_align_cmpxchg ; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]]) #[[ATTR14]] { ; CGSCC-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1 @@ -1187,18 +1187,18 @@ define i64 @infer_align_cmpxchg(ptr align 4 %p) { } define ptr @infer_align_cmpxchg_ptr(ptr align 4 %p, ptr %cmp0, ptr %cmp1) { -; TUNIT: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; TUNIT: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) ; TUNIT-LABEL: define {{[^@]+}}@infer_align_cmpxchg_ptr -; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr nofree [[CMP0:%.*]], ptr nofree [[CMP1:%.*]]) #[[ATTR12]] { +; TUNIT-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr [[CMP0:%.*]], ptr [[CMP1:%.*]]) #[[ATTR12]] { ; TUNIT-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1 ; TUNIT-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3 ; TUNIT-NEXT: [[CMPX:%.*]] = cmpxchg ptr [[ARRAYIDX1]], ptr [[CMP0]], ptr [[CMP1]] seq_cst seq_cst, align 16 ; TUNIT-NEXT: [[RET:%.*]] = extractvalue { ptr, i1 } [[CMPX]], 0 ; TUNIT-NEXT: ret ptr [[RET]] ; -; CGSCC: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; CGSCC: Function Attrs: mustprogress norecurse nounwind willreturn memory(argmem: readwrite) ; CGSCC-LABEL: define {{[^@]+}}@infer_align_cmpxchg_ptr -; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr nofree [[CMP0:%.*]], ptr nofree [[CMP1:%.*]]) #[[ATTR14]] { +; CGSCC-SAME: (ptr nofree align 16 captures(none) [[P:%.*]], ptr [[CMP0:%.*]], ptr [[CMP1:%.*]]) #[[ATTR14]] { ; CGSCC-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, ptr [[P]], i64 1 ; CGSCC-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, ptr [[ARRAYIDX0]], i64 3 ; CGSCC-NEXT: [[CMPX:%.*]] = cmpxchg ptr [[ARRAYIDX1]], ptr [[CMP0]], ptr [[CMP1]] seq_cst seq_cst, align 16 @@ -1230,7 +1230,7 @@ attributes #2 = { null_pointer_is_valid } ; TUNIT: attributes #[[ATTR9]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) } ; TUNIT: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } ; TUNIT: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read) } -; TUNIT: attributes #[[ATTR12]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) } +; TUNIT: attributes #[[ATTR12]] = { mustprogress norecurse nounwind willreturn memory(argmem: readwrite) } ; TUNIT: attributes #[[ATTR13]] = { nofree nosync nounwind } ; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind willreturn memory(read) } ; TUNIT: attributes #[[ATTR15]] = { nofree norecurse nosync nounwind willreturn } @@ -1249,7 +1249,7 @@ attributes #2 = { null_pointer_is_valid } ; CGSCC: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } ; CGSCC: attributes #[[ATTR12]] = { mustprogress nofree nosync nounwind willreturn memory(read) } ; CGSCC: attributes #[[ATTR13]] = { mustprogress nofree nosync nounwind willreturn memory(none) } -; CGSCC: attributes #[[ATTR14]] = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) } +; CGSCC: attributes #[[ATTR14]] = { mustprogress norecurse nounwind willreturn memory(argmem: readwrite) } ; CGSCC: attributes #[[ATTR15]] = { nofree nosync willreturn } ; CGSCC: attributes #[[ATTR16]] = { nofree nosync nounwind } ; CGSCC: attributes #[[ATTR17]] = { nofree willreturn memory(read) } diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll index 5699284128388..33e621c953d13 100644 --- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll +++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll @@ -820,7 +820,7 @@ f: ; TUNIT: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) } ; TUNIT: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn memory(write) } ; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind memory(write) } -; TUNIT: attributes #[[ATTR9]] = { nofree willreturn memory(write) } +; TUNIT: attributes #[[ATTR9]] = { willreturn memory(write) } ; TUNIT: attributes #[[ATTR10]] = { nounwind } ;. ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } @@ -832,7 +832,7 @@ f: ; CGSCC: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) } ; CGSCC: attributes #[[ATTR7]] = { nofree nounwind willreturn memory(write) } ; CGSCC: attributes #[[ATTR8]] = { nofree nosync ... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/196266 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
