[llvm] bf99053 - [Attributor] Improve noalias preservation using reachability
Pankaj Gode via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 13 08:39:16 PDT 2020
Author: Pankaj Gode
Date: 2020-03-13T21:09:08+05:30
New Revision: bf990530ae0f8d7bae77a9c94f4e57fc7fa42b2e
URL: https://github.com/llvm/llvm-project/commit/bf990530ae0f8d7bae77a9c94f4e57fc7fa42b2e
DIFF: https://github.com/llvm/llvm-project/commit/bf990530ae0f8d7bae77a9c94f4e57fc7fa42b2e.diff
LOG: [Attributor] Improve noalias preservation using reachability
Resolution for below fixme:
(ii) Check whether the value is captured in the scope using AANoCapture.
FIXME: This is conservative though, it is better to look at CFG and
check only uses possibly executed before this callsite.
Propagates caller argument's noalias attribute to callee.
Reviewed by: jdoerfert, uenoku
Reviewers: jdoerfert, sstefan1, uenoku
Subscribers: uenoku, sstefan1, hiraditya, llvm-commits
Differential Revision: https://reviews.llvm.org/D71617
Added:
Modified:
llvm/lib/Transforms/IPO/Attributor.cpp
llvm/test/Transforms/Attributor/noalias.ll
llvm/test/Transforms/Attributor/nonnull.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index a7ac4cc21d16..b8f6b217f03a 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -2818,13 +2818,55 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
auto &NoCaptureAA =
A.getAAFor<AANoCapture>(*this, VIRP, /* TrackDependence */ false);
// Check whether the value is captured in the scope using AANoCapture.
- // FIXME: This is conservative though, it is better to look at CFG and
- // check only uses possibly executed before this callsite.
- if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
- LLVM_DEBUG(
- dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
- << " cannot be noalias as it is potentially captured\n");
+ // Look at CFG and check only uses possibly executed before this
+ // callsite.
+ auto UsePred = [&](const Use &U, bool &Follow) -> bool {
+ Instruction *UserI = cast<Instruction>(U.getUser());
+
+ // If user if curr instr and only use.
+ if ((UserI == getCtxI()) && (UserI->getNumUses() == 1))
+ return true;
+
+ const Function *ScopeFn = VIRP.getAnchorScope();
+ if (ScopeFn) {
+ const auto &ReachabilityAA =
+ A.getAAFor<AAReachability>(*this, IRPosition::function(*ScopeFn));
+
+ if (!ReachabilityAA.isAssumedReachable(UserI, getCtxI()))
+ return true;
+
+ if (auto *CB = dyn_cast<CallBase>(UserI)) {
+ if (CB->isArgOperand(&U)) {
+
+ unsigned ArgNo = CB->getArgOperandNo(&U);
+
+ const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
+ *this, IRPosition::callsite_argument(*CB, ArgNo));
+
+ if (NoCaptureAA.isAssumedNoCapture())
+ return true;
+ }
+ }
+ }
+
+ // For cases which can potentially have more users
+ if (isa<GetElementPtrInst>(U) || isa<BitCastInst>(U) || isa<PHINode>(U) ||
+ isa<SelectInst>(U)) {
+ Follow = true;
+ return true;
+ }
+
+ LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *U << "\n");
return false;
+ };
+
+ if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
+ if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
+ LLVM_DEBUG(
+ dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
+ << " cannot be noalias as it is potentially captured\n");
+ return false;
+ }
}
A.recordDependence(NoCaptureAA, *this, DepClassTy::OPTIONAL);
diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll
index f0afc3572141..358528546f9d 100644
--- a/llvm/test/Transforms/Attributor/noalias.ll
+++ b/llvm/test/Transforms/Attributor/noalias.ll
@@ -348,3 +348,48 @@ define internal i32 @ret(i32* %arg) {
ret i32 %l
}
+; Test to propagate noalias where value is assumed to be no-capture in all the
+; uses possibly executed before this callsite.
+; IR referred from musl/src/strtod.c file
+
+%struct._IO_FILE = type { i32, i8*, i8*, i32 (%struct._IO_FILE*)*, i8*, i8*, i8*, i8*, i32 (%struct._IO_FILE*, i8*, i32)*, i32 (%struct._IO_FILE*, i8*, i32)*, i64 (%struct._IO_FILE*, i64, i32)*, i8*, i32, %struct._IO_FILE*, %struct._IO_FILE*, i32, i32, i32, i16, i8, i8, i32, i32, i8*, i64, i8*, i8*, i8*, [4 x i8], i64, i64, %struct._IO_FILE*, %struct._IO_FILE*, %struct.__locale_struct*, [4 x i8] }
+%struct.__locale_struct = type { [6 x %struct.__locale_map*] }
+%struct.__locale_map = type opaque
+
+; Function Attrs: nounwind optsize
+; CHECK: define internal fastcc double @strtox(i8* noalias %s) unnamed_addr
+define internal fastcc double @strtox(i8* %s, i8** %p, i32 %prec) unnamed_addr {
+entry:
+ %f = alloca %struct._IO_FILE, align 8
+ %0 = bitcast %struct._IO_FILE* %f to i8*
+ call void @llvm.lifetime.start.p0i8(i64 144, i8* nonnull %0)
+ %call = call i32 bitcast (i32 (...)* @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull %f, i8* %s)
+ call void @__shlim(%struct._IO_FILE* nonnull %f, i64 0)
+ %call1 = call double @__floatscan(%struct._IO_FILE* nonnull %f, i32 %prec, i32 1)
+ call void @llvm.lifetime.end.p0i8(i64 144, i8* nonnull %0)
+
+ ret double %call1
+}
+
+; Function Attrs: nounwind optsize
+define dso_local double @strtod(i8* noalias %s, i8** noalias %p) {
+entry:
+; CHECK: %call = tail call fastcc double @strtox(i8* noalias %s)
+ %call = tail call fastcc double @strtox(i8* %s, i8** %p, i32 1)
+ ret double %call
+}
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
+
+; Function Attrs: optsize
+declare dso_local i32 @sh_fromstring(...) local_unnamed_addr
+
+; Function Attrs: optsize
+declare dso_local void @__shlim(%struct._IO_FILE*, i64) local_unnamed_addr
+
+; Function Attrs: optsize
+declare dso_local double @__floatscan(%struct._IO_FILE*, i32, i32) local_unnamed_addr
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index d4b0f9af393a..2aae7aa27706 100644
--- a/llvm/test/Transforms/Attributor/nonnull.ll
+++ b/llvm/test/Transforms/Attributor/nonnull.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
-; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_OPM
+; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_OPM
; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_NPM
; Copied from Transforms/FunctoinAttrs/nonnull.ll
More information about the llvm-commits
mailing list