[llvm] 53992c7 - [Attributor] Modularize AANoAliasCallSiteArgument to simplify extensions

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 28 21:40:53 PST 2020


Author: Johannes Doerfert
Date: 2020-01-28T23:39:29-06:00
New Revision: 53992c7bf77702335874c8cf88b526b9c16e1ff5

URL: https://github.com/llvm/llvm-project/commit/53992c7bf77702335874c8cf88b526b9c16e1ff5
DIFF: https://github.com/llvm/llvm-project/commit/53992c7bf77702335874c8cf88b526b9c16e1ff5.diff

LOG: [Attributor] Modularize AANoAliasCallSiteArgument to simplify extensions

This patch modularizes the way we check for no-alias call site arguments
by putting the existing logic into helper functions. The reasoning was
not changed but special cases for readonly/readnone were added.

Added: 
    

Modified: 
    llvm/lib/Transforms/IPO/Attributor.cpp
    llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
    llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
    llvm/test/Transforms/Attributor/align.ll
    llvm/test/Transforms/Attributor/internal-noalias.ll
    llvm/test/Transforms/Attributor/misc.ll
    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 306bfc43dce4..2cac89a9c7c8 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -2504,8 +2504,57 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
       indicateOptimisticFixpoint();
   }
 
-  /// See AbstractAttribute::updateImpl(...).
-  ChangeStatus updateImpl(Attributor &A) override {
+  /// Determine if the underlying value may alias with the call site argument
+  /// \p OtherArgNo of \p ICS (= the underlying call site).
+  bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
+                            const AAMemoryBehavior &MemBehaviorAA,
+                            ImmutableCallSite ICS, unsigned OtherArgNo) {
+    // We do not need to worry about aliasing with the underlying IRP.
+    if (this->getArgNo() == (int)OtherArgNo)
+      return false;
+
+    // If it is not a pointer or pointer vector we do not alias.
+    const Value *ArgOp = ICS.getArgOperand(OtherArgNo);
+    if (!ArgOp->getType()->isPtrOrPtrVectorTy())
+      return false;
+
+    auto &ICSArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
+        *this, IRPosition::callsite_argument(ICS, OtherArgNo),
+        /* TrackDependence */ false);
+
+    // If the argument is readnone, there is no read-write aliasing.
+    if (ICSArgMemBehaviorAA.isAssumedReadNone()) {
+      A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
+      return false;
+    }
+
+    // If the argument is readonly and the underlying value is readonly, there
+    // is no read-write aliasing.
+    bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
+    if (ICSArgMemBehaviorAA.isAssumedReadOnly() && IsReadOnly) {
+      A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
+      A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
+      return false;
+    }
+
+    // We have to utilize actual alias analysis queries so we need the object.
+    if (!AAR)
+      AAR = A.getInfoCache().getAAResultsForFunction(*getAnchorScope());
+
+    // Try to rule it out at the call site.
+    bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
+    LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
+                         "callsite arguments: "
+                      << getAssociatedValue() << " " << *ArgOp << " => "
+                      << (IsAliasing ? "" : "no-") << "alias \n");
+
+    return IsAliasing;
+  }
+
+  bool
+  isKnownNoAliasDueToNoAliasPreservation(Attributor &A, AAResults *&AAR,
+                                         const AAMemoryBehavior &MemBehaviorAA,
+                                         const AANoAlias &NoAliasAA) {
     // 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
@@ -2513,62 +2562,64 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
     // (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);
-    LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] check definition: " << V
-                      << " :: " << NoAliasAA << "\n");
-
-    if (!NoAliasAA.isAssumedNoAlias())
-      return indicatePessimisticFixpoint();
-
-    LLVM_DEBUG(dbgs() << "[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.
+    bool AssociatedValueIsNoAliasAtDef = NoAliasAA.isAssumedNoAlias();
+    if (!AssociatedValueIsNoAliasAtDef) {
+      LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
+                        << " is not no-alias at the definition\n");
+      return false;
+    }
 
-    auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
+    const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
+    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] " << V
+          dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
                  << " cannot be noalias as it is potentially captured\n");
-      return indicatePessimisticFixpoint();
+      return false;
     }
+    A.recordDependence(NoCaptureAA, *this, DepClassTy::OPTIONAL);
 
-    // (iii) Check there is no other pointer argument which could alias with the
-    // value.
+    // Check there is no other pointer argument which could alias with the
+    // value passed at this call site.
     // TODO: AbstractCallSite
     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;
+    for (unsigned OtherArgNo = 0; OtherArgNo < ICS.getNumArgOperands();
+         OtherArgNo++)
+      if (mayAliasWithArgument(A, AAR, MemBehaviorAA, ICS, OtherArgNo))
+        return false;
 
-      if (const Function *F = getAnchorScope()) {
-        if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
-          bool IsAliasing = !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
-          LLVM_DEBUG(dbgs()
-                     << "[NoAliasCSArg] Check alias between "
-                        "callsite arguments "
-                     << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
-                     << getAssociatedValue() << " " << *ArgOp << " => "
-                     << (IsAliasing ? "" : "no-") << "alias \n");
-
-          if (!IsAliasing)
-            continue;
-        }
-      }
-      return indicatePessimisticFixpoint();
+    return true;
+  }
+
+  /// See AbstractAttribute::updateImpl(...).
+  ChangeStatus updateImpl(Attributor &A) override {
+    // If the argument is readnone we are done as there are no accesses via the
+    // argument.
+    auto &MemBehaviorAA =
+        A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(),
+                                     /* TrackDependence */ false);
+    if (MemBehaviorAA.isAssumedReadNone()) {
+      A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
+      return ChangeStatus::UNCHANGED;
     }
 
-    return ChangeStatus::UNCHANGED;
+    const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
+    const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, VIRP,
+                                                  /* TrackDependence */ false);
+
+    AAResults *AAR = nullptr;
+    if (isKnownNoAliasDueToNoAliasPreservation(A, AAR, MemBehaviorAA,
+                                               NoAliasAA)) {
+      LLVM_DEBUG(
+          dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
+      return ChangeStatus::UNCHANGED;
+    }
+
+    return indicatePessimisticFixpoint();
   }
 
   /// See AbstractAttribute::trackStatistics()

diff  --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
index b42d4bc419b2..8ce8789bb8cc 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
@@ -29,7 +29,7 @@ entry:
 ; Function Attrs: nounwind uwtable
 define internal void @callee_t0f(i8* nocapture readnone %tp13, i8* nocapture readnone %tp14, i8* nocapture readnone %tp15, i8* nocapture readnone %tp16, i8* nocapture readnone %tp17, ...) {
 ; CHECK-LABEL: define {{[^@]+}}@callee_t0f
-; CHECK-SAME: (i8* nocapture nofree nonnull readnone [[TP13:%.*]], i8* nocapture nofree nonnull readnone [[TP14:%.*]], i8* nocapture nofree nonnull readnone [[TP15:%.*]], i8* nocapture nofree nonnull readnone [[TP16:%.*]], i8* nocapture nofree nonnull readnone [[TP17:%.*]], ...)
+; CHECK-SAME: (i8* noalias nocapture nofree nonnull readnone [[TP13:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP14:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP15:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP16:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP17:%.*]], ...)
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    ret void
 ;

diff  --git a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
index 2aa6e61eea78..846f0d9468b1 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
@@ -34,9 +34,9 @@ define dso_local i32 @main() {
 ; CHECK-NEXT:    [[ALLOC2:%.*]] = alloca i8, align 8
 ; CHECK-NEXT:    [[THREAD:%.*]] = alloca i64, align 8
 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree readnone align 536870912 null)
-; CHECK-NEXT:    [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* nofree nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
+; CHECK-NEXT:    [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
 ; CHECK-NEXT:    [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
-; CHECK-NEXT:    [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC2]])
+; CHECK-NEXT:    [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* noalias nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC2]])
 ; CHECK-NEXT:    ret i32 0
 ;
 entry:
@@ -64,7 +64,7 @@ entry:
 
 define internal i8* @bar(i8* %arg) {
 ; CHECK-LABEL: define {{[^@]+}}@bar
-; CHECK-SAME: (i8* nofree nonnull readnone returned align 8 dereferenceable(8) [[ARG:%.*]])
+; CHECK-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(8) [[ARG:%.*]])
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    ret i8* bitcast (i8** @GlobalVPtr to i8*)
 ;
@@ -84,7 +84,7 @@ entry:
 
 define internal i8* @buz(i8* %arg) {
 ; CHECK-LABEL: define {{[^@]+}}@buz
-; CHECK-SAME: (i8* nofree nonnull readnone returned align 8 dereferenceable(1) [[ARG:%.*]])
+; CHECK-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) [[ARG:%.*]])
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    ret i8* [[ARG]]
 ;

diff  --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll
index d961a18f642a..9bfd8f72e957 100644
--- a/llvm/test/Transforms/Attributor/align.ll
+++ b/llvm/test/Transforms/Attributor/align.ll
@@ -147,11 +147,11 @@ define align 4 i32* @test7(i32* align 32 %p) #0 {
 ; Function Attrs: nounwind readnone ssp uwtable
 define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@f1b
-; ATTRIBUTOR-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
+; ATTRIBUTOR-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
 ; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
 ; ATTRIBUTOR-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
 ; ATTRIBUTOR:       3:
-; ATTRIBUTOR-NEXT:    [[TMP4:%.*]] = tail call align 8 i8* @f2b(i8* nofree nonnull readnone align 8 dereferenceable(1) @a1)
+; ATTRIBUTOR-NEXT:    [[TMP4:%.*]] = tail call align 8 i8* @f2b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1)
 ; ATTRIBUTOR-NEXT:    [[L:%.*]] = load i8, i8* [[TMP4]], align 8
 ; ATTRIBUTOR-NEXT:    store i8 [[L]], i8* @a1, align 8
 ; ATTRIBUTOR-NEXT:    br label [[TMP5]]
@@ -177,14 +177,14 @@ define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
 define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
 ;
 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@f2b
-; ATTRIBUTOR-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
+; ATTRIBUTOR-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
 ; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = icmp eq i8* @a1, null
 ; ATTRIBUTOR-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
 ; ATTRIBUTOR:       3:
-; ATTRIBUTOR-NEXT:    [[TMP4:%.*]] = tail call i8* @f1b(i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
+; ATTRIBUTOR-NEXT:    [[TMP4:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
 ; ATTRIBUTOR-NEXT:    br label [[TMP7:%.*]]
 ; ATTRIBUTOR:       5:
-; ATTRIBUTOR-NEXT:    [[TMP6:%.*]] = tail call i8* @f3b(i8* nofree nonnull readnone align 16 dereferenceable(1) @a2)
+; ATTRIBUTOR-NEXT:    [[TMP6:%.*]] = tail call i8* @f3b(i8* noalias nofree nonnull readnone align 16 dereferenceable(1) @a2)
 ; ATTRIBUTOR-NEXT:    br label [[TMP7]]
 ; ATTRIBUTOR:       7:
 ; ATTRIBUTOR-NEXT:    [[TMP8:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP6]], [[TMP5]] ]
@@ -211,11 +211,11 @@ define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
 define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
 ;
 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@f3b
-; ATTRIBUTOR-SAME: (i8* nocapture nofree nonnull readnone align 16 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr
+; ATTRIBUTOR-SAME: (i8* noalias nocapture nofree nonnull readnone align 16 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr
 ; ATTRIBUTOR-NEXT:    [[TMP2:%.*]] = icmp eq i8* @a2, null
 ; ATTRIBUTOR-NEXT:    br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
 ; ATTRIBUTOR:       3:
-; ATTRIBUTOR-NEXT:    [[TMP4:%.*]] = tail call i8* @f1b(i8* nofree nonnull readnone align 16 dereferenceable(1) @a2)
+; ATTRIBUTOR-NEXT:    [[TMP4:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 16 dereferenceable(1) @a2)
 ; ATTRIBUTOR-NEXT:    br label [[TMP5]]
 ; ATTRIBUTOR:       5:
 ; ATTRIBUTOR-NEXT:    [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ @a1, [[TMP1:%.*]] ]
@@ -236,7 +236,7 @@ define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
 define align 4 i32* @test7b(i32* align 32 %p) #0 {
 ; ATTRIBUTOR-LABEL: define {{[^@]+}}@test7b
 ; ATTRIBUTOR-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]])
-; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = tail call i8* @f1b(i8* nofree nonnull readnone align 8 dereferenceable(1) @a1)
+; ATTRIBUTOR-NEXT:    [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1)
 ; ATTRIBUTOR-NEXT:    ret i32* [[P]]
 ;
   tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1)
@@ -252,17 +252,17 @@ define void @test8_helper() {
   %ptr2 = tail call align 8 i32* @unknown()
 
   tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0)
-; ATTRIBUTOR: tail call void @test8(i32* readnone align 4 %ptr1, i32* readnone align 4 %ptr1, i32* readnone %ptr0)
+; ATTRIBUTOR: tail call void @test8(i32* noalias readnone align 4 %ptr1, i32* noalias readnone align 4 %ptr1, i32* noalias readnone %ptr0)
   tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
-; ATTRIBUTOR: tail call void @test8(i32* readnone align 8 %ptr2, i32* readnone align 4 %ptr1, i32* readnone align 4 %ptr1)
+; ATTRIBUTOR: tail call void @test8(i32* noalias readnone align 8 %ptr2, i32* noalias readnone align 4 %ptr1, i32* noalias readnone align 4 %ptr1)
   tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
-; ATTRIBUTOR: tail call void @test8(i32* readnone align 8 %ptr2, i32* readnone align 4 %ptr1, i32* readnone align 4 %ptr1)
+; ATTRIBUTOR: tail call void @test8(i32* noalias readnone align 8 %ptr2, i32* noalias readnone align 4 %ptr1, i32* noalias readnone align 4 %ptr1)
   ret void
 }
 
 declare void @user_i32_ptr(i32*) readnone nounwind
 define internal void @test8(i32* %a, i32* %b, i32* %c) {
-; ATTRIBUTOR: define internal void @test8(i32* nocapture readnone align 4 %a, i32* nocapture readnone align 4 %b, i32* nocapture readnone %c)
+; ATTRIBUTOR: define internal void @test8(i32* noalias nocapture readnone align 4 %a, i32* noalias nocapture readnone align 4 %b, i32* noalias nocapture readnone %c)
   call void @user_i32_ptr(i32* %a)
   call void @user_i32_ptr(i32* %b)
   call void @user_i32_ptr(i32* %c)

diff  --git a/llvm/test/Transforms/Attributor/internal-noalias.ll b/llvm/test/Transforms/Attributor/internal-noalias.ll
index fd6e17bc77f7..6c380b514ce3 100644
--- a/llvm/test/Transforms/Attributor/internal-noalias.ll
+++ b/llvm/test/Transforms/Attributor/internal-noalias.ll
@@ -21,11 +21,7 @@ entry:
 }
 
 
-; FIXME: Should be something like this.
-; define internal i32 @noalias_args_argmem(i32* noalias nocapture readonly %A, i32* noalias nocapture readonly %B)
-; CHECK: define internal i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %A, i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %B)
-
-;
+; CHECK: define internal i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %A, i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) %B)
 define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 {
 entry:
   %0 = load i32, i32* %A, align 4
@@ -44,5 +40,34 @@ entry:
   ret i32 %add
 }
 
+; CHECK: define internal i32 @noalias_args_argmem_ro(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) %A, i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) %B)
+define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 {
+  %t0 = load i32, i32* %A, align 4
+  %t1 = load i32, i32* %B, align 4
+  %add = add nsw i32 %t0, %t1
+  ret i32 %add
+}
+
+define i32 @visible_local_2() {
+  %B = alloca i32, align 4
+  store i32 5, i32* %B, align 4
+  %call = call i32 @noalias_args_argmem_ro(i32* %B, i32* %B)
+  ret i32 %call
+}
+
+; CHECK: define internal i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) %B)
+define internal i32 @noalias_args_argmem_rn(i32* %A, i32* %B) #1 {
+  %t0 = load i32, i32* %B, align 4
+  store i32 0, i32* %B
+  ret i32 %t0
+}
+
+define i32 @visible_local_3() {
+  %B = alloca i32, align 4
+  store i32 5, i32* %B, align 4
+  %call = call i32 @noalias_args_argmem_rn(i32* %B, i32* %B)
+  ret i32 %call
+}
+
 attributes #0 = { noinline nounwind uwtable willreturn }
 attributes #1 = { argmemonly noinline nounwind uwtable willreturn}

diff  --git a/llvm/test/Transforms/Attributor/misc.ll b/llvm/test/Transforms/Attributor/misc.ll
index 3ca99c0c23bb..4fdb0bc280d3 100644
--- a/llvm/test/Transforms/Attributor/misc.ll
+++ b/llvm/test/Transforms/Attributor/misc.ll
@@ -10,7 +10,7 @@ define internal void @internal(void (i8*)* %fp) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[TMP:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT:    call void @foo(i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) undef)
+; CHECK-NEXT:    call void @foo(i32* noalias nofree nonnull readnone align 4 dereferenceable(4) undef)
 ; CHECK-NEXT:    call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
 ; CHECK-NEXT:    call void @callback1(void (i32*)* nonnull @foo)
 ; CHECK-NEXT:    call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
@@ -24,7 +24,7 @@ define internal void @internal(void (i8*)* %fp) {
 ; DECL_CS-NEXT:  entry:
 ; DECL_CS-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; DECL_CS-NEXT:    [[TMP:%.*]] = bitcast i32* [[A]] to i8*
-; DECL_CS-NEXT:    call void @foo(i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) undef)
+; DECL_CS-NEXT:    call void @foo(i32* noalias nofree nonnull readnone align 4 dereferenceable(4) undef)
 ; DECL_CS-NEXT:    call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
 ; DECL_CS-NEXT:    call void @callback1(void (i32*)* nonnull @foo)
 ; DECL_CS-NEXT:    call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
@@ -52,7 +52,7 @@ define void @external(void (i8*)* %fp) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[TMP:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT:    call void @foo(i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) undef)
+; CHECK-NEXT:    call void @foo(i32* noalias nofree nonnull readnone align 4 dereferenceable(4) undef)
 ; CHECK-NEXT:    call void @callback1(void (i32*)* nonnull @foo)
 ; CHECK-NEXT:    call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
 ; CHECK-NEXT:    call void @callback2(void (i8*)* [[FP]])
@@ -67,7 +67,7 @@ define void @external(void (i8*)* %fp) {
 ; DECL_CS-NEXT:  entry:
 ; DECL_CS-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; DECL_CS-NEXT:    [[TMP:%.*]] = bitcast i32* [[A]] to i8*
-; DECL_CS-NEXT:    call void @foo(i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) undef)
+; DECL_CS-NEXT:    call void @foo(i32* noalias nofree nonnull readnone align 4 dereferenceable(4) undef)
 ; DECL_CS-NEXT:    call void @callback1(void (i32*)* nonnull @foo)
 ; DECL_CS-NEXT:    call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
 ; DECL_CS-NEXT:    call void @callback2(void (i8*)* [[FP]])

diff  --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll
index f7f6297f639f..f22b66a12d1f 100644
--- a/llvm/test/Transforms/Attributor/noalias.ll
+++ b/llvm/test/Transforms/Attributor/noalias.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 < %s | FileCheck %s
+; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 < %s | FileCheck %s
 
 ; TEST 1 - negative.
 
@@ -152,27 +152,39 @@ define i8* @test8(i32* %0) nounwind uwtable {
 
 ; TEST 9
 ; Simple Argument Test
-declare void @use_i8(i8* nocapture) readnone
+declare void @use_i8(i8* nocapture)
 define internal void @test9a(i8* %a, i8* %b) {
 ; CHECK: define internal void @test9a()
   ret void
 }
 define internal void @test9b(i8* %a, i8* %b) {
-; CHECK: define internal void @test9b(i8* noalias nocapture readnone %a, i8* nocapture readnone %b)
+; FIXME: %b should be noalias
+; CHECK: define internal void @test9b(i8* noalias nocapture %a, i8* nocapture %b)
   call void @use_i8(i8* %a)
   call void @use_i8(i8* %b)
   ret void
 }
+define internal void @test9c(i8* %a, i8* %b, i8* %c) {
+; CHECK: define internal void @test9c(i8* noalias nocapture %a, i8* nocapture %b, i8* nocapture %c)
+  call void @use_i8(i8* %a)
+  call void @use_i8(i8* %b)
+  call void @use_i8(i8* %c)
+  ret void
+}
 define void @test9_helper(i8* %a, i8* %b) {
-; CHECK: define void @test9_helper(i8* nocapture readnone %a, i8* nocapture readnone %b)
+; CHECK: define void @test9_helper(i8* nocapture %a, i8* nocapture %b)
 ; CHECK:  tail call void @test9a()
 ; CHECK:  tail call void @test9a()
-; CHECK:  tail call void @test9b(i8* noalias nocapture readnone %a, i8* nocapture readnone %b)
-; CHECK:  tail call void @test9b(i8* noalias nocapture readnone %b, i8* noalias nocapture readnone %a)
+; CHECK:  tail call void @test9b(i8* noalias nocapture %a, i8* nocapture %b)
+; CHECK:  tail call void @test9b(i8* noalias nocapture %b, i8* noalias nocapture %a)
+; CHECK:  tail call void @test9c(i8* noalias nocapture %a, i8* nocapture %b, i8* nocapture %b)
+; CHECK:  tail call void @test9c(i8* noalias nocapture %b, i8* noalias nocapture %a, i8* noalias nocapture %a)
   tail call void @test9a(i8* noalias %a, i8* %b)
   tail call void @test9a(i8* noalias %b, i8* noalias %a)
   tail call void @test9b(i8* noalias %a, i8* %b)
   tail call void @test9b(i8* noalias %b, i8* noalias %a)
+  tail call void @test9c(i8* noalias %a, i8* %b, i8* %b)
+  tail call void @test9c(i8* noalias %b, i8* noalias %a, i8* noalias %a)
   ret void
 }
 

diff  --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index bf366708c61a..7420a39b8907 100644
--- a/llvm/test/Transforms/Attributor/nonnull.ll
+++ b/llvm/test/Transforms/Attributor/nonnull.ll
@@ -167,7 +167,7 @@ define void @test13_helper() {
 }
 declare void @use_i8_ptr(i8* nofree) readnone nounwind
 define internal void @test13(i8* %a, i8* %b, i8* %c) {
-; ATTRIBUTOR: define internal void @test13(i8* nocapture nofree nonnull readnone %a, i8* nocapture nofree readnone %b, i8* nocapture nofree readnone %c)
+; ATTRIBUTOR: define internal void @test13(i8* noalias nocapture nofree nonnull readnone %a, i8* noalias nocapture nofree readnone %b, i8* noalias nocapture nofree readnone %c)
   call void @use_i8_ptr(i8* %a)
   call void @use_i8_ptr(i8* %b)
   call void @use_i8_ptr(i8* %c)
@@ -536,7 +536,7 @@ define  i32* @g1() {
 }
 
 declare void @use_i32_ptr(i32*) readnone nounwind
-; ATTRIBUTOR: define internal void @called_by_weak(i32* nocapture nonnull readnone %a)
+; ATTRIBUTOR: define internal void @called_by_weak(i32* noalias nocapture nonnull readnone %a)
 define internal void @called_by_weak(i32* %a) {
   call void @use_i32_ptr(i32* %a)
   ret void
@@ -550,7 +550,7 @@ define weak_odr void @weak_caller(i32* nonnull %a) {
 }
 
 ; Expect nonnull
-; ATTRIBUTOR: define internal void @control(i32* nocapture nonnull readnone align 16 dereferenceable(8) %a)
+; ATTRIBUTOR: define internal void @control(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) %a)
 define internal void @control(i32* dereferenceable(4) %a) {
   call void @use_i32_ptr(i32* %a)
   ret void


        


More information about the llvm-commits mailing list