From: Johannes Doerfert Date: Sat, 10 Oct 2020 14:39:51 +0000 (-0500) Subject: [Attributor][FIX] Properly check uses in the call not uses of the call X-Git-Tag: llvmorg-13-init~7933 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=30e5a1f0be027b981e415e00691883bc52957976;p=platform%2Fupstream%2Fllvm.git [Attributor][FIX] Properly check uses in the call not uses of the call In the AANoAlias logic we determine if a pointer may have been captured before a call. We need to look at other uses in the call not uses of the call. The new code is not perfect as it does not allow trivial cases where the call has multiple arguments but it is at least not unsound and a TODO was added. --- diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 98bd770..ac8e36d 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -2584,8 +2584,11 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl { auto UsePred = [&](const Use &U, bool &Follow) -> bool { Instruction *UserI = cast(U.getUser()); - // If user if curr instr and only use. - if (UserI == getCtxI() && UserI->hasOneUse()) + // If UserI is the curr instruction and there is a single potential use of + // the value in UserI we allow the use. + // TODO: We should inspect the operands and allow those that cannot alias + // with the value. + if (UserI == getCtxI() && UserI->getNumOperands() == 1) return true; const Function *ScopeFn = VIRP.getAnchorScope(); @@ -4075,7 +4078,8 @@ struct AANoCaptureImpl : public AANoCapture { return; } - const Function *F = isArgumentPosition() ? getAssociatedFunction() : AnchorScope; + const Function *F = + isArgumentPosition() ? getAssociatedFunction() : AnchorScope; // Check what state the associated function can actually capture. if (F) @@ -4306,8 +4310,8 @@ private: ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) { const IRPosition &IRP = getIRPosition(); - const Value *V = - isArgumentPosition() ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue(); + const Value *V = isArgumentPosition() ? IRP.getAssociatedArgument() + : &IRP.getAssociatedValue(); if (!V) return indicatePessimisticFixpoint(); diff --git a/llvm/test/Transforms/Attributor/memory_locations.ll b/llvm/test/Transforms/Attributor/memory_locations.ll index 64f8468..2ec31dc 100644 --- a/llvm/test/Transforms/Attributor/memory_locations.ll +++ b/llvm/test/Transforms/Attributor/memory_locations.ll @@ -603,7 +603,7 @@ define i8 @readnone_caller(i1 %c) { define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) { ; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind ; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2 -; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) [[ATTR8]] { +; IS__TUNIT____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) [[ATTR8]] { ; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 ; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__TUNIT____: t: @@ -616,7 +616,7 @@ define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) { ; ; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind ; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2 -; IS__CGSCC____-SAME: (i8* noalias nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) [[ATTR8]] { +; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) [[ATTR8]] { ; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1 ; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] ; IS__CGSCC____: t: diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll index 539f383..6aa6816 100644 --- a/llvm/test/Transforms/Attributor/noalias.ll +++ b/llvm/test/Transforms/Attributor/noalias.ll @@ -573,7 +573,7 @@ define internal i32 @ret(i32* %arg) { ; Function Attrs: nounwind optsize define internal fastcc double @strtox(i8* %s, i8** %p, i32 %prec) unnamed_addr { ; CHECK-LABEL: define {{[^@]+}}@strtox -; CHECK-SAME: (i8* noalias [[S:%.*]]) unnamed_addr { +; CHECK-SAME: (i8* [[S:%.*]]) unnamed_addr { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]], align 8 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]] to i8* @@ -601,7 +601,7 @@ define dso_local double @strtod(i8* noalias %s, i8** noalias %p) { ; CHECK-LABEL: define {{[^@]+}}@strtod ; CHECK-SAME: (i8* noalias [[S:%.*]], i8** noalias nocapture nofree readnone [[P:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = tail call fastcc double @strtox(i8* noalias [[S]]) +; CHECK-NEXT: [[CALL:%.*]] = tail call fastcc double @strtox(i8* [[S]]) ; CHECK-NEXT: ret double [[CALL]] ; entry: