[PATCH] D73528: [Inliner][NoAlias] Use call site attributes too

Johannes Doerfert via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 27 22:25:42 PST 2020


jdoerfert created this revision.
jdoerfert added a reviewer: hfinkel.
Herald added subscribers: bollu, hiraditya.
Herald added a reviewer: sstefan1.
Herald added a project: LLVM.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73528

Files:
  llvm/lib/Transforms/Utils/InlineFunction.cpp
  llvm/test/Transforms/Inline/noalias-calls.ll


Index: llvm/test/Transforms/Inline/noalias-calls.ll
===================================================================
--- llvm/test/Transforms/Inline/noalias-calls.ll
+++ llvm/test/Transforms/Inline/noalias-calls.ll
@@ -22,6 +22,23 @@
   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 @@
 ; 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 @@
 ; 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}
+
Index: llvm/lib/Transforms/Utils/InlineFunction.cpp
===================================================================
--- llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -925,7 +925,7 @@
   SmallVector<const Argument *, 4> 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())
@@ -979,6 +979,7 @@
       if (!NI)
         continue;
 
+      const CallBase *Call = nullptr;
       bool IsArgMemOnlyCall = false, IsFuncCall = false;
       SmallVector<const Value *, 2> PtrArgs;
 
@@ -992,7 +993,7 @@
         PtrArgs.push_back(CXI->getPointerOperand());
       else if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I))
         PtrArgs.push_back(RMWI->getPointerOperand());
-      else if (const auto *Call = dyn_cast<CallBase>(I)) {
+      else if ((Call = dyn_cast<CallBase>(I))) {
         // If we know that the call does not access memory, then we'll still
         // know that about the inlined clone of this call site, and we don't
         // need to add metadata.
@@ -1059,7 +1060,7 @@
         // completely describe the aliasing properties using alias.scope
         // metadata (and, thus, won't add any).
         if (const Argument *A = dyn_cast<Argument>(V)) {
-          if (!A->hasNoAliasAttr())
+          if (!Call->paramHasAttr(A->getArgNo(), Attribute::NoAlias))
             UsesAliasingPtr = true;
         } else {
           UsesAliasingPtr = true;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D73528.240772.patch
Type: text/x-patch
Size: 3992 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200128/839bca98/attachment.bin>


More information about the llvm-commits mailing list