From 342357c5687efcb6bf8191684212507226085317 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Tue, 28 Jan 2020 00:20:03 -0600 Subject: [PATCH] [Inliner][NoAlias] Use call site attributes too If we had `noalias` on an argument the inliner created alias scope metadata already. However, the call site `noalias` annotation was not considered. Since the Attributor can derive such call site `noalias` annotation we should treat them the same as argument annotations. Reviewed By: hfinkel Differential Revision: https://reviews.llvm.org/D73528 --- llvm/lib/Transforms/Utils/InlineFunction.cpp | 4 ++-- llvm/test/Transforms/Inline/noalias-calls.ll | 34 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 90da27c..8089377 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -925,7 +925,7 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, SmallVector NoAliasArgs; for (const Argument &Arg : CalledFunc->args()) - if (Arg.hasNoAliasAttr() && !Arg.use_empty()) + if (CS.paramHasAttr(Arg.getArgNo(), Attribute::NoAlias) && !Arg.use_empty()) NoAliasArgs.push_back(&Arg); if (NoAliasArgs.empty()) @@ -1058,7 +1058,7 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, // completely describe the aliasing properties using alias.scope // metadata (and, thus, won't add any). if (const Argument *A = dyn_cast(V)) { - if (!A->hasNoAliasAttr()) + if (!CS.paramHasAttr(A->getArgNo(), Attribute::NoAlias)) UsesAliasingPtr = true; } else { UsesAliasingPtr = true; diff --git a/llvm/test/Transforms/Inline/noalias-calls.ll b/llvm/test/Transforms/Inline/noalias-calls.ll index a5643cd..965f5ce 100644 --- a/llvm/test/Transforms/Inline/noalias-calls.ll +++ b/llvm/test/Transforms/Inline/noalias-calls.ll @@ -22,6 +22,23 @@ entry: ret void } +define void @hello_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #1 { +entry: + %l = alloca i8, i32 512, align 1 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 0) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %b, i8* align 16 %c, i64 16, i1 0) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %c, i64 16, i1 0) + call void @hey() + call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %l, i8* align 16 %c, i64 16, i1 0) + ret void +} + +define void @foo_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 { +entry: + tail call void @hello_cs(i8* noalias %a, i8* noalias %c, i8* %b) + ret void +} + ; CHECK: define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 { ; CHECK: entry: ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 false) #1, !noalias !0 @@ -32,6 +49,16 @@ entry: ; CHECK: ret void ; CHECK: } +; CHECK: define void @foo_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 { +; CHECK: entry: +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %b, i64 16, i1 false) #1, !noalias !6 +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %b, i8* align 16 %c, i64 16, i1 false) #1, !noalias !9 +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %a, i8* align 16 %c, i64 16, i1 false) #1, !alias.scope !11 +; CHECK: call void @hey() #1, !noalias !11 +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 %{{.*}}, i8* align 16 %c, i64 16, i1 false) #1, !noalias !9 +; CHECK: ret void +; CHECK: } + attributes #0 = { nounwind argmemonly willreturn } attributes #1 = { nounwind } attributes #2 = { nounwind uwtable } @@ -43,3 +70,10 @@ attributes #2 = { nounwind uwtable } ; CHECK: !4 = distinct !{!4, !2, !"hello: %a"} ; CHECK: !5 = !{!4, !1} +; CHECK: !6 = !{!7} +; CHECK: !7 = distinct !{!7, !8, !"hello_cs: %c"} +; CHECK: !8 = distinct !{!8, !"hello_cs"} +; CHECK: !9 = !{!10} +; CHECK: !10 = distinct !{!10, !8, !"hello_cs: %a"} +; CHECK: !11 = !{!10, !7} + -- 2.7.4