]> granicus.if.org Git - llvm/commitdiff
[Attributor][FIX] NullPointerIsDefined needs the pointer AS (AANonNull)
authorJohannes Doerfert <jdoerfert@anl.gov>
Sun, 13 Oct 2019 20:48:26 +0000 (20:48 +0000)
committerJohannes Doerfert <jdoerfert@anl.gov>
Sun, 13 Oct 2019 20:48:26 +0000 (20:48 +0000)
Also includes a shortcut via AADereferenceable if possible.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374737 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/Attributor.cpp
test/Transforms/FunctionAttrs/noalias_returned.ll
test/Transforms/FunctionAttrs/nonnull.ll
test/Transforms/FunctionAttrs/nounwind.ll
test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll

index d7c49a248dee4da7da24ca571a3be0c5abf8d0cd..7dfc802179c3302eccb2d6308cddacc076991b79 100644 (file)
@@ -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 {
index dab08bca3d9d3a87dc926d25517de8294b4addbf..72de6fb282b0277c79730a24ce21a2b167246b1a 100644 (file)
@@ -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.
 
index 21e5ae1f7ec89b615911de38f61d81e9bd204f07..84d6720032f457aa8e063bab4b0cad633f6fec8f 100644 (file)
@@ -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*)
index 858780589228300bdd3f2af5dd892c702e714cdf..b5b968e3fc9babb933aab6b5f150fab764215e80 100644 (file)
@@ -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
index a3ac9ffa667d676d828af90d1f9bdfa634911b63..5f9e477679c3a81336ad4e06bc828d2f8410d5c8 100644 (file)
@@ -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