[llvm] r215657 - Add noalias metadata for general calls (not just memory intrinsics) during inlining

Hal Finkel hfinkel at anl.gov
Thu Aug 14 09:44:03 PDT 2014


Author: hfinkel
Date: Thu Aug 14 11:44:03 2014
New Revision: 215657

URL: http://llvm.org/viewvc/llvm-project?rev=215657&view=rev
Log:
Add noalias metadata for general calls (not just memory intrinsics) during inlining

When preserving noalias function parameter attributes by adding noalias
metadata in the inliner, we should do this for general function calls (not just
memory intrinsics). The logic is very similar to what already existed (except
that we want to add this metadata even for functions taking no relevant
parameters). This metadata can be used by ModRef queries in the caller after
inlining.

This addresses the first part of PR20500. Adding noalias metadata during
inlining is still turned off by default.

Added:
    llvm/trunk/test/Transforms/Inline/noalias-calls.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp

Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=215657&r1=215656&r2=215657&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Thu Aug 14 11:44:03 2014
@@ -449,17 +449,28 @@ static void AddAliasScopeMetadata(CallSi
         PtrArgs.push_back(CXI->getPointerOperand());
       else if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I))
         PtrArgs.push_back(RMWI->getPointerOperand());
-      else if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
-        PtrArgs.push_back(MI->getRawDest());
-        if (const MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI))
-          PtrArgs.push_back(MTI->getRawSource());
+      else if (ImmutableCallSite ICS = ImmutableCallSite(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.
+        if (ICS.doesNotAccessMemory())
+          continue;
+
+        for (ImmutableCallSite::arg_iterator AI = ICS.arg_begin(),
+             AE = ICS.arg_end(); AI != AE; ++AI)
+	  // We need to check the underlying objects of all arguments, not just
+	  // the pointer arguments, because we might be passing pointers as
+	  // integers, etc.
+          // FIXME: If we know that the call only accesses pointer arguments,
+          // then we only need to check the pointer arguments.
+          PtrArgs.push_back(*AI);
       }
 
       // If we found no pointers, then this instruction is not suitable for
       // pairing with an instruction to receive aliasing metadata.
-      // Simplification during cloning could make this happen, and skip these
-      // cases for now.
-      if (PtrArgs.empty())
+      // However, if this is a call, this we might just alias with none of the
+      // noalias arguments.
+      if (PtrArgs.empty() && !isa<CallInst>(I) && !isa<InvokeInst>(I))
         continue;
 
       // It is possible that there is only one underlying object, but you

Added: llvm/trunk/test/Transforms/Inline/noalias-calls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/noalias-calls.ll?rev=215657&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/Inline/noalias-calls.ll (added)
+++ llvm/trunk/test/Transforms/Inline/noalias-calls.ll Thu Aug 14 11:44:03 2014
@@ -0,0 +1,41 @@
+; RUN: opt -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #0
+declare void @hey() #0
+
+define void @hello(i8* noalias nocapture %a, i8* noalias nocapture readonly %c, i8* nocapture %b) #1 {
+entry:
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 16, i32 16, i1 0)
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c, i64 16, i32 16, i1 0)
+  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %c, i64 16, i32 16, i1 0)
+  call void @hey()
+  ret void
+}
+
+define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #1 {
+entry:
+  tail call void @hello(i8* %a, i8* %c, i8* %b)
+  ret void
+}
+
+; CHECK: define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #1 {
+; CHECK: entry:
+; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %b, i64 16, i32 16, i1 false) #0, !alias.scope !0, !noalias !3
+; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c, i64 16, i32 16, i1 false) #0, !alias.scope !3, !noalias !0
+; CHECK:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %c, i64 16, i32 16, i1 false) #0, !alias.scope !5
+; CHECK:   call void @hey() #0, !noalias !5
+; CHECK:   ret void
+; CHECK: }
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind uwtable }
+
+; CHECK: !0 = metadata !{metadata !1}
+; CHECK: !1 = metadata !{metadata !1, metadata !2, metadata !"hello: %a"}
+; CHECK: !2 = metadata !{metadata !2, metadata !"hello"}
+; CHECK: !3 = metadata !{metadata !4}
+; CHECK: !4 = metadata !{metadata !4, metadata !2, metadata !"hello: %c"}
+; CHECK: !5 = metadata !{metadata !1, metadata !4}
+





More information about the llvm-commits mailing list