summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-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