diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 76492182b05c47..7a0e6484fcc687 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -1517,13 +1517,32 @@ struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating { // sense to specialize attributes for call sites arguments instead of // redirecting requests to the callee argument. Argument *Arg = getAssociatedArgument(); - if (!Arg) + if (Arg) { + const IRPosition &ArgPos = IRPosition::argument(*Arg); + auto &ArgAA = + A.getAAFor(*this, ArgPos, DepClassTy::REQUIRED); + if (ArgAA.getState().isValidState()) + return translateAndAddState(A, ArgAA, 0, *cast(getCtxI()), + /* FromCallee */ true); + } + + const auto &NoCaptureAA = + A.getAAFor(*this, getIRPosition(), DepClassTy::OPTIONAL); + + if (!NoCaptureAA.isAssumedNoCapture()) return indicatePessimisticFixpoint(); - const IRPosition &ArgPos = IRPosition::argument(*Arg); - auto &ArgAA = - A.getAAFor(*this, ArgPos, DepClassTy::REQUIRED); - return translateAndAddState(A, ArgAA, 0, *cast(getCtxI()), - /* FromCallee */ true); + + bool IsKnown = false; + if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown)) + return ChangeStatus::UNCHANGED; + bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown); + + ChangeStatus Changed = ChangeStatus::UNCHANGED; + handleAccess(A, *getCtxI(), getAssociatedValue(), nullptr, + ReadOnly ? AccessKind::AK_MAY_READ + : AccessKind::AK_MAY_READ_WRITE, + 0, Changed, nullptr, AA::OffsetAndSize::Unknown); + return Changed; } /// See AbstractAttribute::trackStatistics() diff --git a/llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll b/llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll index d7edc9d484be3d..1438dcba6bbd1d 100644 --- a/llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll +++ b/llvm/test/Transforms/Attributor/heap_to_stack_gpu.ll @@ -407,11 +407,10 @@ define i32 @irreducible_cfg(i32 %0) { ; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1 ; IS________OPM-NEXT: br label [[TMP8]] ; IS________OPM: 15: -; IS________OPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4 -; IS________OPM-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP3]] to i8* -; IS________OPM-NEXT: call void @free(i8* nocapture noundef [[TMP17]]) -; IS________OPM-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP3]], align 4 -; IS________OPM-NEXT: ret i32 [[TMP18]] +; IS________OPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8* +; IS________OPM-NEXT: call void @free(i8* nocapture noundef [[TMP16]]) +; IS________OPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4 +; IS________OPM-NEXT: ret i32 [[TMP17]] ; ; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg ; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { @@ -439,10 +438,9 @@ define i32 @irreducible_cfg(i32 %0) { ; IS________NPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1 ; IS________NPM-NEXT: br label [[TMP8]] ; IS________NPM: 15: -; IS________NPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4 ; IS________NPM-NEXT: call void @free(i8* nocapture noundef [[TMP2]]) -; IS________NPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4 -; IS________NPM-NEXT: ret i32 [[TMP17]] +; IS________NPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4 +; IS________NPM-NEXT: ret i32 [[TMP16]] ; %2 = call noalias i8* @malloc(i64 4) %3 = bitcast i8* %2 to i32* diff --git a/llvm/test/Transforms/Attributor/pointer-info.ll b/llvm/test/Transforms/Attributor/pointer-info.ll index 73b6016afed0fa..8450d887f98e00 100644 --- a/llvm/test/Transforms/Attributor/pointer-info.ll +++ b/llvm/test/Transforms/Attributor/pointer-info.ll @@ -21,13 +21,12 @@ define void @foo(i8* %ptr) { ; ; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@foo -; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR0:[0-9]+]] { +; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[PTR:%.*]]) #[[ATTR0:[0-9]+]] { ; IS__CGSCC____-NEXT: entry: ; IS__CGSCC____-NEXT: [[TMP0:%.*]] = alloca [[STRUCT_TEST_A:%.*]], align 8 ; IS__CGSCC____-NEXT: br label [[CALL_BR:%.*]] ; IS__CGSCC____: call.br: ; IS__CGSCC____-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_TEST_A]], %struct.test.a* [[TMP0]], i64 0, i32 2 -; IS__CGSCC____-NEXT: store i8* [[PTR]], i8** [[TMP1]], align 8 ; IS__CGSCC____-NEXT: tail call void @bar(%struct.test.a* noalias nocapture nofree noundef nonnull readnone byval([[STRUCT_TEST_A]]) align 8 dereferenceable(24) [[TMP0]]) #[[ATTR2:[0-9]+]] ; IS__CGSCC____-NEXT: ret void ; diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll index 57c0ac8b85adfc..988c3be5b46271 100644 --- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll +++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info-struct.ll @@ -29,13 +29,15 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16 ; @GlobalS = internal constant %struct.S { i32 42, double 3.140000e+00, ptr null }, align 8 +declare void @harmless_use(ptr nocapture readonly) nofree norecurse nosync nounwind readnone willreturn nocallback + ;. ; CHECK: @[[GLOBALS:[a-zA-Z0-9_$"\\.-]+]] = internal constant [[STRUCT_S:%.*]] { i32 42, double 3.140000e+00, ptr null }, align 8 ;. define i32 @testOneFieldGlobalS() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS -; CHECK-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-SAME: () #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[IF_END:%.*]] ; CHECK: if.then: @@ -54,6 +56,7 @@ define i32 @testOneFieldGlobalS() { ; entry: %i = load i32, ptr @GlobalS, align 8 + call void @harmless_use(ptr @GlobalS) %cmp = icmp ne i32 %i, 42 br i1 %cmp, label %if.then, label %if.end @@ -89,7 +92,7 @@ if.end7: ; preds = %if.then5, %if.end4 define i32 @testOneFieldGlobalS_type_mismatch() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_type_mismatch -; CHECK-SAME: () #[[ATTR0]] { +; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[I:%.*]] = load double, ptr @GlobalS, align 8 ; CHECK-NEXT: [[IC:%.*]] = fptosi double [[I]] to i32 @@ -155,7 +158,7 @@ if.end7: ; preds = %if.then5, %if.end4 define i32 @testOneFieldGlobalS_byte_offset_wrong() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@testOneFieldGlobalS_byte_offset_wrong -; CHECK-SAME: () #[[ATTR0]] { +; CHECK-SAME: () #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[I:%.*]] = load i32, ptr getelementptr inbounds (i32, ptr @GlobalS, i32 1), align 8 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[I]], 42 @@ -217,5 +220,6 @@ if.end7: ; preds = %if.then5, %if.end4 ret i32 %r.2 } ;. -; CHECK: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree norecurse nosync nounwind readnone willreturn } +; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } ;. diff --git a/llvm/test/Transforms/OpenMP/parallel_deletion.ll b/llvm/test/Transforms/OpenMP/parallel_deletion.ll index ec2f3e219d21d2..28c7c5210c3920 100644 --- a/llvm/test/Transforms/OpenMP/parallel_deletion.ll +++ b/llvm/test/Transforms/OpenMP/parallel_deletion.ll @@ -279,6 +279,7 @@ entry: ; ; FIXME: We do not realize that `a` is dead and all accesses to it can be removed ; making the parallel regions readonly and deletable. +; This is still true except the (non-atomic) reduction update is already deleted. define void @delete_parallel_2() { ; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() { ; CHECK-NEXT: entry: @@ -553,10 +554,6 @@ define internal void @.omp_outlined..6(i32* noalias %.global_tid., i32* noalias ; CHECK-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]] ; CHECK-NEXT: ] ; CHECK: .omp.reduction.case1: -; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[A]], align 4 -; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[A1]], align 4 -; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]] -; CHECK-NEXT: store i32 [[ADD]], i32* [[A]], align 4 ; CHECK-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* noundef nonnull @[[GLOB2]], i32 [[TMP2]], [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var) ; CHECK-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]] ; CHECK: .omp.reduction.case2: