summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Doerfert <jdoerfert@anl.gov>2019-10-13 20:47:16 +0000
committerJohannes Doerfert <jdoerfert@anl.gov>2019-10-13 20:47:16 +0000
commit8ee410c75ec416ea02dabeddd03fb062ab5dc92e (patch)
tree4402cd576b41e4e5be8b0a4d9c3604d768e4243d
parentdb6efb017f246e2492ccd00613d079de96d8f705 (diff)
downloadbcm5719-llvm-8ee410c75ec416ea02dabeddd03fb062ab5dc92e.tar.gz
bcm5719-llvm-8ee410c75ec416ea02dabeddd03fb062ab5dc92e.zip
[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. llvm-svn: 374736
-rw-r--r--llvm/include/llvm/Transforms/IPO/Attributor.h6
-rw-r--r--llvm/lib/Transforms/IPO/Attributor.cpp25
-rw-r--r--llvm/test/Transforms/FunctionAttrs/nocapture.ll18
-rw-r--r--llvm/test/Transforms/FunctionAttrs/nonnull.ll4
-rw-r--r--llvm/test/Transforms/FunctionAttrs/readattrs.ll2
5 files changed, 36 insertions, 19 deletions
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 2b7a4a04b08..3dbe0fcd76e 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -1128,6 +1128,12 @@ struct IntegerState : public AbstractState {
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".
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index dadf3722a6f..d7c49a248de 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -3838,17 +3838,23 @@ struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
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::updateImpl(Attributor &A) {
// 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();
diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
index 6f2699a3bdb..e0580849983 100644
--- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -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 %bitno) readnone nounwind {
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
diff --git a/llvm/test/Transforms/FunctionAttrs/nonnull.ll b/llvm/test/Transforms/FunctionAttrs/nonnull.ll
index f893e1db889..21e5ae1f7ec 100644
--- a/llvm/test/Transforms/FunctionAttrs/nonnull.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nonnull.ll
@@ -198,7 +198,7 @@ bb4: ; preds = %bb1
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: ; preds = %bb4, %bb
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)
diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll
index 76075684bff..cccdeaad765 100644
--- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -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
OpenPOWER on IntegriCloud