[llvm] r374736 - [Attributor][MemBehavior] Fallback to the function state for arguments

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 13 13:47:16 PDT 2019


Author: jdoerfert
Date: Sun Oct 13 13:47:16 2019
New Revision: 374736

URL: http://llvm.org/viewvc/llvm-project?rev=374736&view=rev
Log:
[Attributor][MemBehavior] Fallback to the function state for arguments

Even if an argument is captured, we cannot have an effect the function
does not have. This is fine except for the special case of `inalloca` as
it does not behave by the rules.

TODO: Maybe the special rule for `inalloca` is wrong after all.

Modified:
    llvm/trunk/include/llvm/Transforms/IPO/Attributor.h
    llvm/trunk/lib/Transforms/IPO/Attributor.cpp
    llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll
    llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll
    llvm/trunk/test/Transforms/FunctionAttrs/readattrs.ll

Modified: llvm/trunk/include/llvm/Transforms/IPO/Attributor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/Attributor.h?rev=374736&r1=374735&r2=374736&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/IPO/Attributor.h (original)
+++ llvm/trunk/include/llvm/Transforms/IPO/Attributor.h Sun Oct 13 13:47:16 2019
@@ -1128,6 +1128,12 @@ struct IntegerState : public AbstractSta
     return *this;
   }
 
+  /// Remove the bits in \p BitsEncoding from the "known bits".
+  IntegerState &removeKnownBits(base_t BitsEncoding) {
+    Known = (Known & ~BitsEncoding);
+    return *this;
+  }
+
   /// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
   IntegerState &intersectAssumedBits(base_t BitsEncoding) {
     // Make sure we never loose any "known bits".

Modified: llvm/trunk/lib/Transforms/IPO/Attributor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Attributor.cpp?rev=374736&r1=374735&r2=374736&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Attributor.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp Sun Oct 13 13:47:16 2019
@@ -3838,17 +3838,23 @@ struct AAMemoryBehaviorArgument : AAMemo
   void initialize(Attributor &A) override {
     AAMemoryBehaviorFloating::initialize(A);
 
-    // TODO: From readattrs.ll: "inalloca parameters are always
-    //                           considered written"
-    if (hasAttr({Attribute::InAlloca}))
-      removeAssumedBits(NO_WRITES);
-
     // Initialize the use vector with all direct uses of the associated value.
     Argument *Arg = getAssociatedArgument();
     if (!Arg || !Arg->getParent()->hasExactDefinition())
       indicatePessimisticFixpoint();
   }
 
+  ChangeStatus manifest(Attributor &A) override {
+    // TODO: From readattrs.ll: "inalloca parameters are always
+    //                           considered written"
+    if (hasAttr({Attribute::InAlloca})) {
+      removeKnownBits(NO_WRITES);
+      removeAssumedBits(NO_WRITES);
+    }
+    return AAMemoryBehaviorFloating::manifest(A);
+  }
+
+
   /// See AbstractAttribute::trackStatistics()
   void trackStatistics() const override {
     if (isAssumedReadNone())
@@ -4017,10 +4023,13 @@ ChangeStatus AAMemoryBehaviorFloating::u
 
   // Make sure the value is not captured (except through "return"), if
   // it is, any information derived would be irrelevant anyway as we cannot
-  // check the potential aliases introduced by the capture.
+  // check the potential aliases introduced by the capture. However, no need
+  // to fall back to anythign less optimistic than the function state.
   const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
-  if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned())
-    return indicatePessimisticFixpoint();
+  if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
+    S.intersectAssumedBits(FnMemAA.getAssumed());
+    return ChangeStatus::CHANGED;
+  }
 
   // The current assumed state used to determine a change.
   auto AssumedState = S.getAssumed();

Modified: llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll?rev=374736&r1=374735&r2=374736&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll Sun Oct 13 13:47:16 2019
@@ -11,14 +11,16 @@ define i32* @c1(i32* %q) {
 	ret i32* %q
 }
 
-; EITHER: define void @c2(i32* %q)
+; FNATTR: define void @c2(i32* %q)
+; ATTRIBUTOR: define void @c2(i32* writeonly %q)
 ; It would also be acceptable to mark %q as readnone. Update @c3 too.
 define void @c2(i32* %q) {
 	store i32* %q, i32** @g
 	ret void
 }
 
-; EITHER: define void @c3(i32* %q)
+; FNATTR: define void @c3(i32* %q)
+; ATTRIBUTOR: define void @c3(i32* writeonly %q)
 define void @c3(i32* %q) {
 	call void @c2(i32* %q)
 	ret void
@@ -39,7 +41,8 @@ l1:
 
 @lookup_table = global [2 x i1] [ i1 0, i1 1 ]
 
-; EITHER: define i1 @c5(i32* %q, i32 %bitno)
+; FNATTR: define i1 @c5(i32* %q, i32 %bitno)
+; ATTRIBUTOR: define i1 @c5(i32* readonly %q, i32 %bitno)
 define i1 @c5(i32* %q, i32 %bitno) {
 	%tmp = ptrtoint i32* %q to i32
 	%tmp2 = lshr i32 %tmp, %bitno
@@ -52,8 +55,7 @@ define i1 @c5(i32* %q, i32 %bitno) {
 
 declare void @throw_if_bit_set(i8*, i8) readonly
 
-; FNATTR: define i1 @c6(i8* readonly %q, i8 %bit)
-; ATTRIBUTOR: define i1 @c6(i8* %q, i8 %bit)
+; EITHER: define i1 @c6(i8* readonly %q, i8 %bit)
 define i1 @c6(i8* %q, i8 %bit) personality i32 (...)* @__gxx_personality_v0 {
 	invoke void @throw_if_bit_set(i8* %q, i8 %bit)
 		to label %ret0 unwind label %ret1
@@ -75,8 +77,7 @@ define i1* @lookup_bit(i32* %q, i32 %bit
 	ret i1* %lookup
 }
 
-; FNATTR: define i1 @c7(i32* readonly %q, i32 %bitno)
-; ATTRIBUTOR: define i1 @c7(i32* %q, i32 %bitno)
+; EITHER: define i1 @c7(i32* readonly %q, i32 %bitno)
 define i1 @c7(i32* %q, i32 %bitno) {
 	%ptr = call i1* @lookup_bit(i32* %q, i32 %bitno)
 	%val = load i1, i1* %ptr
@@ -271,7 +272,8 @@ entry:
 }
 
 @g3 = global i8* null
-; EITHER: define void @captureStrip(i8* %p)
+; FNATTR: define void @captureStrip(i8* %p)
+; ATTRIBUTOR: define void @captureStrip(i8* writeonly %p)
 define void @captureStrip(i8* %p) {
   %b = call i8* @llvm.strip.invariant.group.p0i8(i8* %p)
   store i8* %b, i8** @g3

Modified: llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll?rev=374736&r1=374735&r2=374736&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll Sun Oct 13 13:47:16 2019
@@ -198,7 +198,7 @@ bb4:
 
 bb6:                                              ; preds = %bb1
 ; FIXME: missing nonnull. It should be @f2(i32* nonnull %arg)
-; ATTRIBUTOR: %tmp7 = tail call nonnull i32* @f2(i32* %arg)
+; ATTRIBUTOR: %tmp7 = tail call nonnull i32* @f2(i32* readonly %arg)
   %tmp7 = tail call i32* @f2(i32* %arg)
   ret i32* %tmp7
 
@@ -209,7 +209,7 @@ bb9:
 
 define internal i32* @f2(i32* %arg) {
 ; FIXME: missing nonnull. It should be nonnull @f2(i32* nonnull %arg) 
-; ATTRIBUTOR: define internal nonnull i32* @f2(i32* %arg)
+; ATTRIBUTOR: define internal nonnull i32* @f2(i32* readonly %arg)
 bb:
 
 ; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg) 

Modified: llvm/trunk/test/Transforms/FunctionAttrs/readattrs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/readattrs.ll?rev=374736&r1=374735&r2=374736&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/readattrs.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/readattrs.ll Sun Oct 13 13:47:16 2019
@@ -39,7 +39,7 @@ define void @test4_2(i8* %p) {
 }
 
 ; FNATTR: define void @test5(i8** nocapture %p, i8* %q)
-; ATTRIBUTOR: define void @test5(i8** nocapture nonnull writeonly dereferenceable(8) %p, i8* %q)
+; ATTRIBUTOR: define void @test5(i8** nocapture nonnull writeonly dereferenceable(8) %p, i8* writeonly %q)
 ; Missed optz'n: we could make %q readnone, but don't break test6!
 define void @test5(i8** %p, i8* %q) {
   store i8* %q, i8** %p




More information about the llvm-commits mailing list