[llvm] r371590 - [Attributor] Implement "noalias" callsite argument deduction

Hideto Ueno via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 11 00:00:34 PDT 2019


Author: uenoku
Date: Wed Sep 11 00:00:33 2019
New Revision: 371590

URL: http://llvm.org/viewvc/llvm-project?rev=371590&view=rev
Log:
[Attributor] Implement "noalias" callsite argument deduction

Summary: Now, `nocapture` is deduced in Attributor therefore, this patch introduces deduction for `noalias` callsite argument using `nocapture`.

Reviewers: jdoerfert, sstefan1

Reviewed By: jdoerfert

Subscribers: lebedev.ri, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67286

Modified:
    llvm/trunk/lib/Transforms/IPO/Attributor.cpp
    llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll

Modified: llvm/trunk/lib/Transforms/IPO/Attributor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Attributor.cpp?rev=371590&r1=371589&r2=371590&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Attributor.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp Wed Sep 11 00:00:33 2019
@@ -1672,8 +1672,9 @@ struct AANoAliasFloating final : AANoAli
 
   /// See AbstractAttribute::initialize(...).
   void initialize(Attributor &A) override {
-    // TODO: It isn't sound to initialize as the same with `AANoAliasImpl`
-    // because `noalias` may not be valid in the current position.
+    AANoAliasImpl::initialize(A);
+    if (isa<AllocaInst>(getAnchorValue()))
+      indicateOptimisticFixpoint();
   }
 
   /// See AbstractAttribute::updateImpl(...).
@@ -1711,8 +1712,53 @@ struct AANoAliasCallSiteArgument final :
 
   /// See AbstractAttribute::updateImpl(...).
   ChangeStatus updateImpl(Attributor &A) override {
-    // TODO: Implement this.
-    return indicatePessimisticFixpoint();
+    // We can deduce "noalias" if the following conditions hold.
+    // (i)   Associated value is assumed to be noalias in the definition.
+    // (ii)  Associated value is assumed to be no-capture in all the uses
+    //       possibly executed before this callsite.
+    // (iii) There is no other pointer argument which could alias with the
+    //       value.
+
+    const Value &V = getAssociatedValue();
+    const IRPosition IRP = IRPosition::value(V);
+
+    // (i) Check whether noalias holds in the definition.
+
+    auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
+
+    if (!NoAliasAA.isAssumedNoAlias())
+      return indicatePessimisticFixpoint();
+
+    LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
+                      << " is assumed NoAlias in the definition\n");
+
+    // (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.
+
+    auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
+    if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned())
+      return indicatePessimisticFixpoint();
+
+    // (iii) Check there is no other pointer argument which could alias with the
+    // value.
+    ImmutableCallSite ICS(&getAnchorValue());
+    for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
+      if (getArgNo() == (int)i)
+        continue;
+      const Value *ArgOp = ICS.getArgOperand(i);
+      if (!ArgOp->getType()->isPointerTy())
+        continue;
+
+      // TODO: Use AliasAnalysis
+      //       AAResults& AAR = ..;
+      //       if(AAR.isNoAlias(&getAssociatedValue(), ArgOp))
+      //          return indicatePessimitisicFixpoint();
+
+      return indicatePessimisticFixpoint();
+    }
+
+    return ChangeStatus::UNCHANGED;
   }
 
   /// See AbstractAttribute::trackStatistics()

Modified: llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll?rev=371590&r1=371589&r2=371590&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll Wed Sep 11 00:00:33 2019
@@ -191,3 +191,79 @@ define void @test11(i8* noalias %a) {
   tail call void @test11_helper(i8* %a, i8* %a)
   ret void
 }
+
+
+; TEST 12
+; CallSite Argument
+declare void @use_nocapture(i8* nocapture)
+declare void @use(i8*)
+define void @test12_1() {
+; CHECK-LABEL: @test12_1(
+; CHECK-NEXT:    [[A:%.*]] = alloca i8, align 4
+; CHECK-NEXT:    [[B:%.*]] = tail call noalias i8* @malloc(i64 4)
+; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nonnull align 4 dereferenceable(1) [[A]])
+; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias nonnull align 4 dereferenceable(1) [[A]])
+; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias [[B]])
+; CHECK-NEXT:    tail call void @use_nocapture(i8* noalias [[B]])
+; CHECK-NEXT:    ret void
+;
+  %A = alloca i8, align 4
+  %B = tail call noalias i8* @malloc(i64 4)
+  tail call void @use_nocapture(i8* %A)
+  tail call void @use_nocapture(i8* %A)
+  tail call void @use_nocapture(i8* %B)
+  tail call void @use_nocapture(i8* %B)
+  ret void
+}
+
+define void @test12_2(){
+; CHECK-LABEL: @test12_2(
+; CHECK-NEXT:    [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
+; FIXME: This should be @use_nocapture(i8* noalias [[A]])
+; CHECK-NEXT:    tail call void @use_nocapture(i8* [[A]])
+; FIXME: This should be @use_nocapture(i8* noalias [[A]])
+; CHECK-NEXT:    tail call void @use_nocapture(i8* [[A]])
+; CHECK-NEXT:    tail call void @use(i8* [[A]])
+; CHECK-NEXT:    tail call void @use_nocapture(i8* [[A]])
+; CHECK-NEXT:    ret void
+;
+  %A = tail call noalias i8* @malloc(i64 4)
+  tail call void @use_nocapture(i8* %A)
+  tail call void @use_nocapture(i8* %A)
+  tail call void @use(i8* %A)
+  tail call void @use_nocapture(i8* %A)
+  ret void
+}
+
+declare void @two_args(i8* nocapture , i8* nocapture)
+define void @test12_3(){
+; CHECK-LABEL: @test12_3(
+  %A = tail call noalias i8* @malloc(i64 4)
+; CHECK: tail call void @two_args(i8* %A, i8* %A)
+  tail call void @two_args(i8* %A, i8* %A)
+  ret void
+}
+
+define void @test12_4(){
+; CHECK-LABEL: @test12_4(
+  %A = tail call noalias i8* @malloc(i64 4)
+  %B = tail call noalias i8* @malloc(i64 4)
+  %A_0 = getelementptr i8, i8* %A, i64 0
+  %A_1 = getelementptr i8, i8* %A, i64 1
+  %B_0 = getelementptr i8, i8* %B, i64 0
+
+; FIXME: This should be @two_args(i8* noalias %A, i8* noalias %B)
+; CHECK: tail call void @two_args(i8* %A, i8* %B)
+  tail call void @two_args(i8* %A, i8* %B)
+
+; CHECK: tail call void @two_args(i8* %A, i8* %A_0)
+  tail call void @two_args(i8* %A, i8* %A_0)
+
+; CHECK: tail call void @two_args(i8* %A, i8* %A_1)
+  tail call void @two_args(i8* %A, i8* %A_1)
+
+; FIXME: This should be @two_args(i8* noalias %A_0, i8* noalias %B_0)
+; CHECK: tail call void @two_args(i8* %A_0, i8* %B_0)
+  tail call void @two_args(i8* %A_0, i8* %B_0)
+  ret void
+}




More information about the llvm-commits mailing list