diff options
5 files changed, 28 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index d7c49a248de..7dfc802179c 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -1588,11 +1588,16 @@ static int64_t getKnownNonNullAndDerefBytesForUse(  }  struct AANonNullImpl : AANonNull { -  AANonNullImpl(const IRPosition &IRP) : AANonNull(IRP) {} +  AANonNullImpl(const IRPosition &IRP) +      : AANonNull(IRP), +        NullIsDefined(NullPointerIsDefined( +            getAnchorScope(), +            getAssociatedValue().getType()->getPointerAddressSpace())) {}    /// See AbstractAttribute::initialize(...).    void initialize(Attributor &A) override { -    if (hasAttr({Attribute::NonNull, Attribute::Dereferenceable})) +    if (!NullIsDefined && +        hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))        indicateOptimisticFixpoint();      else        AANonNull::initialize(A); @@ -1612,6 +1617,10 @@ struct AANonNullImpl : AANonNull {    const std::string getAsStr() const override {      return getAssumed() ? "nonnull" : "may-null";    } + +  /// Flag to determine if the underlying value can be null and still allow +  /// valid accesses. +  const bool NullIsDefined;  };  /// NonNull attribute for a floating value. @@ -1644,6 +1653,12 @@ struct AANonNullFloating      if (isKnownNonNull())        return Change; +    if (!NullIsDefined) { +      const auto &DerefAA = A.getAAFor<AADereferenceable>(*this, getIRPosition()); +      if (DerefAA.getAssumedDereferenceableBytes()) +        return Change; +    } +      const DataLayout &DL = A.getDataLayout();      auto VisitValueCB = [&](Value &V, AAAlign::StateType &T, @@ -1651,7 +1666,7 @@ struct AANonNullFloating        const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));        if (!Stripped && this == &AA) {          if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, -                            /* TODO: CtxI */ nullptr, +                            /* CtxI */ getCtxI(),                              /* TODO: DT */ nullptr))            T.indicatePessimisticFixpoint();        } else { diff --git a/llvm/test/Transforms/FunctionAttrs/noalias_returned.ll b/llvm/test/Transforms/FunctionAttrs/noalias_returned.ll index dab08bca3d9..72de6fb282b 100644 --- a/llvm/test/Transforms/FunctionAttrs/noalias_returned.ll +++ b/llvm/test/Transforms/FunctionAttrs/noalias_returned.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 < %s | FileCheck %s +; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s  ; TEST 1 - negative. diff --git a/llvm/test/Transforms/FunctionAttrs/nonnull.ll b/llvm/test/Transforms/FunctionAttrs/nonnull.ll index 21e5ae1f7ec..84d6720032f 100644 --- a/llvm/test/Transforms/FunctionAttrs/nonnull.ll +++ b/llvm/test/Transforms/FunctionAttrs/nonnull.ll @@ -523,6 +523,13 @@ define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {    ret i32 addrspace(3)* %q  } +; FNATTR:     define i32 addrspace(3)* @as(i32 addrspace(3)* readnone returned dereferenceable(4) %p) +; FIXME: We should propagate dereferenceable here but *not* nonnull +; ATTRIBUTOR: define dereferenceable_or_null(4) i32 addrspace(3)* @as(i32 addrspace(3)* readnone returned dereferenceable(4) dereferenceable_or_null(4) %p) +define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) { +  ret i32 addrspace(3)* %p +} +  ; BOTH: define internal nonnull i32* @g2()  define internal i32* @g2() {    ret i32* inttoptr (i64 4 to i32*) diff --git a/llvm/test/Transforms/FunctionAttrs/nounwind.ll b/llvm/test/Transforms/FunctionAttrs/nounwind.ll index 85878058922..b5b968e3fc9 100644 --- a/llvm/test/Transforms/FunctionAttrs/nounwind.ll +++ b/llvm/test/Transforms/FunctionAttrs/nounwind.ll @@ -1,5 +1,5 @@  ; RUN: opt < %s -functionattrs -S | FileCheck %s -; RUN: opt < %s -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 -S | FileCheck %s --check-prefix=ATTRIBUTOR +; RUN: opt < %s -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 -S | FileCheck %s --check-prefix=ATTRIBUTOR  ; TEST 1  ; CHECK: Function Attrs: norecurse nounwind readnone diff --git a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll index a3ac9ffa667..5f9e477679c 100644 --- a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll +++ b/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll @@ -1,4 +1,4 @@ -; RUN: opt -functionattrs -enable-nonnull-arg-prop -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=6 -S < %s | FileCheck %s +; RUN: opt -functionattrs -enable-nonnull-arg-prop -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 -S < %s | FileCheck %s  ;  ; This is an evolved example to stress test SCC parameter attribute propagation.  ; The SCC in this test is made up of the following six function, three of which  | 

