[llvm] r369328 - [Attributor] Use structured deduction for AANonNull

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 19 23:02:39 PDT 2019


Author: jdoerfert
Date: Mon Aug 19 23:02:39 2019
New Revision: 369328

URL: http://llvm.org/viewvc/llvm-project?rev=369328&view=rev
Log:
[Attributor] Use structured deduction for AANonNull

Summary:
What D66126 did for AAAlign, this patch does for AANonNull. Agian, the
logic becomes more concise and localized. Again, returned poiners are
not annotated properly but that will not be an issue if this lands with
the "on-demand" generation of attributes. First improvements due to the
genericValueTraversal are already visible.

Reviewers: sstefan1, uenoku

Subscribers: hiraditya, bollu, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66128

Modified:
    llvm/trunk/lib/Transforms/IPO/Attributor.cpp
    llvm/trunk/test/Transforms/FunctionAttrs/align.ll
    llvm/trunk/test/Transforms/FunctionAttrs/dereferenceable.ll
    llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll
    llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll
    llvm/trunk/test/Transforms/FunctionAttrs/noreturn_async.ll
    llvm/trunk/test/Transforms/FunctionAttrs/noreturn_sync.ll
    llvm/trunk/test/Transforms/FunctionAttrs/nosync.ll

Modified: llvm/trunk/lib/Transforms/IPO/Attributor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Attributor.cpp?rev=369328&r1=369327&r2=369328&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Attributor.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp Mon Aug 19 23:02:39 2019
@@ -139,7 +139,7 @@ ChangeStatus llvm::operator&(ChangeStatu
 template <typename AAType, typename StateTy>
 bool genericValueTraversal(
     Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
-    const function_ref<void(Value &, StateTy &, bool)> &VisitValueCB,
+    const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
     int MaxValues = 8) {
 
   const AAIsDead *LivenessAA = nullptr;
@@ -204,7 +204,8 @@ bool genericValueTraversal(
     }
 
     // Once a leaf is reached we inform the user through the callback.
-    VisitValueCB(*V, State, Iteration > 1);
+    if (!VisitValueCB(*V, State, Iteration > 1))
+      return false;
   } while (!Worklist.empty());
 
   // All values have been visited.
@@ -468,6 +469,12 @@ ChangeStatus clampStateAndIndicateChange
   return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
                                    : ChangeStatus::CHANGED;
 }
+
+template <>
+ChangeStatus clampStateAndIndicateChange<BooleanState>(BooleanState &S,
+                                                       const BooleanState &R) {
+  return clampStateAndIndicateChange<IntegerState>(S, R);
+}
 ///}
 
 /// Clamp the information known for all returned values of a function
@@ -888,7 +895,7 @@ ChangeStatus AAReturnedValuesImpl::updat
   };
 
   // Callback for a leaf value returned by the associated function.
-  auto VisitValueCB = [](Value &Val, RVState &RVS, bool) {
+  auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
     auto Size = RVS.RetValsMap[&Val].size();
     RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
     bool Inserted = RVS.RetValsMap[&Val].size() != Size;
@@ -898,6 +905,7 @@ ChangeStatus AAReturnedValuesImpl::updat
         dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
                << " => " << RVS.RetInsts.size() << "\n";
     });
+    return true;
   };
 
   // Helper method to invoke the generic value traversal.
@@ -1245,141 +1253,111 @@ using AANoFreeCallSite = AANoFreeFunctio
 struct AANonNullImpl : AANonNull {
   AANonNullImpl(const IRPosition &IRP) : AANonNull(IRP) {}
 
-  /// See AbstractAttribute::getAsStr().
-  const std::string getAsStr() const override {
-    return getAssumed() ? "nonnull" : "may-null";
-  }
-
   /// See AbstractAttribute::initialize(...).
   void initialize(Attributor &A) override {
     if (hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
       indicateOptimisticFixpoint();
   }
 
-  /// Generate a predicate that checks if a given value is assumed nonnull.
-  /// The generated function returns true if a value satisfies any of
-  /// following conditions.
-  /// (i) A value is known nonZero(=nonnull).
-  /// (ii) A value is associated with AANonNull and its isAssumedNonNull() is
-  /// true.
-  std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)>
-  generatePredicate(Attributor &);
-};
-
-std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)>
-AANonNullImpl::generatePredicate(Attributor &A) {
-  // FIXME: The `AAReturnedValues` should provide the predicate with the
-  // `ReturnInst` vector as well such that we can use the control flow sensitive
-  // version of `isKnownNonZero`. This should fix `test11` in
-  // `test/Transforms/FunctionAttrs/nonnull.ll`
-
-  std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
-      [&](Value &RV, const SmallPtrSetImpl<ReturnInst *> &RetInsts) -> bool {
-    if (isKnownNonZero(&RV, A.getDataLayout()))
-      return true;
+  /// See AbstractAttribute::getAsStr().
+  const std::string getAsStr() const override {
+    return getAssumed() ? "nonnull" : "may-null";
+  }
+};
 
-    if (ImmutableCallSite ICS = ImmutableCallSite(&RV))
-      if (ICS.hasRetAttr(Attribute::NonNull))
-        return true;
+/// NonNull attribute for a floating value.
+struct AANonNullFloating : AANonNullImpl {
+  AANonNullFloating(const IRPosition &IRP) : AANonNullImpl(IRP) {}
 
-    auto *NonNullAA = A.getAAFor<AANonNull>(*this, IRPosition::value(RV));
-    return (NonNullAA && NonNullAA->isAssumedNonNull());
-  };
+  /// See AbstractAttribute::initialize(...).
+  void initialize(Attributor &A) override {
+    AANonNullImpl::initialize(A);
 
-  return Pred;
-}
+    if (isAtFixpoint())
+      return;
 
-/// NonNull attribute for function return value.
-struct AANonNullReturned final : AANonNullImpl {
-  AANonNullReturned(const IRPosition &IRP) : AANonNullImpl(IRP) {}
+    const IRPosition &IRP = getIRPosition();
+    const Value &V = IRP.getAssociatedValue();
+    const DataLayout &DL = A.getDataLayout();
+
+    // TODO: This context sensitive query should be removed once we can do
+    // context sensitive queries in the genericValueTraversal below.
+    if (isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, IRP.getCtxI(),
+                       /* TODO: DT */ nullptr))
+      indicateOptimisticFixpoint();
+  }
 
   /// See AbstractAttribute::updateImpl(...).
   ChangeStatus updateImpl(Attributor &A) override {
-    std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
-        this->generatePredicate(A);
+    const DataLayout &DL = A.getDataLayout();
 
-    if (!A.checkForAllReturnedValuesAndReturnInsts(Pred, *this))
+    auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
+                            bool Stripped) -> bool {
+      if (isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr,
+                         /* TODO: CtxI */ nullptr,
+                         /* TODO: DT */ nullptr)) {
+        // Known non-zero, all good.
+      } else if (const auto *AA =
+                     A.getAAFor<AANonNull>(*this, IRPosition::value(V))) {
+        // Try to use abstract attribute information.
+        if (!AA->isAssumedNonNull())
+          T.indicatePessimisticFixpoint();
+      } else {
+        // IR information was not sufficient and we did not find an abstract
+        // attribute to use. TODO: on-demand attribute creation!
+        T.indicatePessimisticFixpoint();
+      }
+      return T.isValidState();
+    };
+
+    StateType T;
+    if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
+                                                     T, VisitValueCB))
       return indicatePessimisticFixpoint();
-    return ChangeStatus::UNCHANGED;
+
+    return clampStateAndIndicateChange(getState(), T);
   }
 
   /// See AbstractAttribute::trackStatistics()
   void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
 };
 
-/// NonNull attribute for function argument.
-struct AANonNullArgument final : AANonNullImpl {
-  AANonNullArgument(const IRPosition &IRP) : AANonNullImpl(IRP) {}
-
-  /// See AbstractAttribute::updateImpl(...).
-  ChangeStatus updateImpl(Attributor &A) override {
-    unsigned ArgNo = getArgNo();
-
-    // Callback function
-    std::function<bool(CallSite)> CallSiteCheck = [&](CallSite CS) {
-      assert(CS && "Sanity check: Call site was not initialized properly!");
-
-      IRPosition CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
-      if (CSArgPos.hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
-        return true;
-
-      // Check that NonNullAA is AANonNullCallSiteArgument.
-      if (auto *NonNullAA = A.getAAFor<AANonNullImpl>(*this, CSArgPos)) {
-        ImmutableCallSite ICS(&NonNullAA->getAnchorValue());
-        if (ICS && CS.getInstruction() == ICS.getInstruction())
-          return NonNullAA->isAssumedNonNull();
-        return false;
-      }
+/// NonNull attribute for function return value.
+struct AANonNullReturned final : AAReturnedFromReturnedValues<AANonNullImpl> {
+  AANonNullReturned(const IRPosition &IRP)
+      : AAReturnedFromReturnedValues<AANonNullImpl>(IRP) {}
 
-      Value *V = CS.getArgOperand(ArgNo);
-      if (isKnownNonZero(V, A.getDataLayout()))
-        return true;
+  /// See AbstractAttribute::trackStatistics()
+  void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
+};
 
-      return false;
-    };
-    if (!A.checkForAllCallSites(CallSiteCheck, *this, true))
-      return indicatePessimisticFixpoint();
-    return ChangeStatus::UNCHANGED;
-  }
+/// NonNull attribute for function argument.
+struct AANonNullArgument final
+    : AAArgumentFromCallSiteArguments<AANonNullImpl> {
+  AANonNullArgument(const IRPosition &IRP)
+      : AAArgumentFromCallSiteArguments<AANonNullImpl>(IRP) {}
 
   /// See AbstractAttribute::trackStatistics()
   void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
 };
 
-/// NonNull attribute for a call site argument.
-struct AANonNullCallSiteArgument final : AANonNullImpl {
-  AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullImpl(IRP) {}
-
-  /// See AbstractAttribute::initialize(...).
-  void initialize(Attributor &A) override {
-    AANonNullImpl::initialize(A);
-    if (!isKnownNonNull() &&
-        isKnownNonZero(&getAssociatedValue(), A.getDataLayout()))
-      indicateOptimisticFixpoint();
-  }
+struct AANonNullCallSiteArgument final : AANonNullFloating {
+  AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
 
-  /// See AbstractAttribute::updateImpl(Attributor &A).
-  ChangeStatus updateImpl(Attributor &A) override {
-    // NOTE: Never look at the argument of the callee in this method.
-    //       If we do this, "nonnull" is always deduced because of the
-    //       assumption.
-
-    Value &V = getAssociatedValue();
-    auto *NonNullAA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
-
-    if (!NonNullAA || !NonNullAA->isAssumedNonNull())
-      return indicatePessimisticFixpoint();
+  /// See AbstractAttribute::trackStatistics()
+  void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
+};
 
-    return ChangeStatus::UNCHANGED;
-  }
+/// NonNull attribute for a call site return position.
+struct AANonNullCallSiteReturned final
+    : AACallSiteReturnedFromReturned<AANonNullImpl> {
+  AANonNullCallSiteReturned(const IRPosition &IRP)
+      : AACallSiteReturnedFromReturned<AANonNullImpl>(IRP) {}
 
   /// See AbstractAttribute::trackStatistics()
-  void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
+  void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
 };
 
-/// NonNull attribute deduction for a call sites.
-using AANonNullCallSiteReturned = AANonNullReturned;
-
 /// ------------------------ No-Recurse Attributes ----------------------------
 
 struct AANoRecurseImpl : public AANoRecurse {
@@ -2245,7 +2223,8 @@ struct AAAlignFloating : AAAlignImpl {
   ChangeStatus updateImpl(Attributor &A) override {
     const DataLayout &DL = A.getDataLayout();
 
-    auto VisitValueCB = [&](Value &V, AAAlign::StateType &T, bool Stripped) {
+    auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
+                            bool Stripped) -> bool {
       if (!Stripped &&
           getIRPosition().getPositionKind() == IRPosition::IRP_FLOAT) {
         // Use only IR information if we did not strip anything.
@@ -2262,6 +2241,7 @@ struct AAAlignFloating : AAAlignImpl {
         T.takeKnownMaximum(V.getPointerAlignment(DL));
         T.indicatePessimisticFixpoint();
       }
+      return T.isValidState();
     };
 
     StateType T;

Modified: llvm/trunk/test/Transforms/FunctionAttrs/align.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/align.ll?rev=369328&r1=369327&r2=369328&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/align.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/align.ll Mon Aug 19 23:02:39 2019
@@ -92,7 +92,7 @@ define internal i8* @f1(i8* readnone %0)
 ; FIXME: Until we have "on-demand" attribute generation we do not determine the
 ;        alignment for the return value here.
 ;             define internal nonnull align 8 i8* @f1(i8* nonnull readnone align 8 %0)
-; ATTRIBUTOR: define internal nonnull i8* @f1(i8* nonnull readnone align 8 %0)
+; ATTRIBUTOR: define internal i8* @f1(i8* nonnull readnone align 8 %0)
   %2 = icmp eq i8* %0, null
   br i1 %2, label %3, label %5
 
@@ -111,7 +111,7 @@ define internal i8* @f2(i8* readnone %0)
 ; FIXME: Until we have "on-demand" attribute generation we do not determine the
 ;        alignment for the return value here.
 ;             define internal nonnull align 8 i8* @f2(i8* nonnull readnone align 8 %0)
-; ATTRIBUTOR: define internal nonnull i8* @f2(i8* nonnull readnone align 8 %0)
+; ATTRIBUTOR: define internal i8* @f2(i8* nonnull readnone align 8 %0)
   %2 = icmp eq i8* %0, null
   br i1 %2, label %5, label %3
 
@@ -136,7 +136,7 @@ define internal i8* @f3(i8* readnone %0)
 ; FIXME: Until we have "on-demand" attribute generation we do not determine the
 ;        alignment for the return value here.
 ;             define internal nonnull align 8 i8* @f3(i8* nonnull readnone align 16 %0)
-; ATTRIBUTOR: define internal nonnull i8* @f3(i8* nonnull readnone align 16 %0)
+; ATTRIBUTOR: define internal i8* @f3(i8* nonnull readnone align 16 %0)
   %2 = icmp eq i8* %0, null
   br i1 %2, label %3, label %5
 

Modified: llvm/trunk/test/Transforms/FunctionAttrs/dereferenceable.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/dereferenceable.ll?rev=369328&r1=369327&r2=369328&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/dereferenceable.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/dereferenceable.ll Mon Aug 19 23:02:39 2019
@@ -22,20 +22,23 @@ define i32* @test2(i32* dereferenceable_
 ; TEST 3
 ; GEP inbounds
 define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr {
-; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_1(i32* nonnull dereferenceable(8) %0)
+;             define nonnull dereferenceable(4) i32* @test3_1(i32* nonnull dereferenceable(8) %0)
+; ATTRIBUTOR: define dereferenceable_or_null(4) i32* @test3_1(i32* nonnull dereferenceable(8) %0)
   %ret = getelementptr inbounds i32, i32* %0, i64 1
   ret i32* %ret
 }
 
 define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr {
 ; FIXME: Argument should be mark dereferenceable because of GEP `inbounds`.
-; ATTRIBUTOR: define nonnull dereferenceable(16) i32* @test3_2(i32* dereferenceable_or_null(32) %0)
+;             define nonnull dereferenceable(16) i32* @test3_2(i32* dereferenceable_or_null(32) %0)
+; ATTRIBUTOR: define dereferenceable_or_null(16) i32* @test3_2(i32* dereferenceable_or_null(32) %0)
   %ret = getelementptr inbounds i32, i32* %0, i64 4
   ret i32* %ret
 }
 
 define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 %2) local_unnamed_addr {
-; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_3(i32* nonnull dereferenceable(8) %0, i32* nonnull dereferenceable(16) %1, i1 %2) local_unnamed_addr
+;             define nonnull dereferenceable(4) i32* @test3_3(i32* nonnull dereferenceable(8) %0, i32* nonnull dereferenceable(16) %1, i1 %2) local_unnamed_addr
+; ATTRIBUTOR: define dereferenceable_or_null(4) i32* @test3_3(i32* nonnull dereferenceable(8) %0, i32* nonnull dereferenceable(16) %1, i1 %2) local_unnamed_addr
   %ret1 = getelementptr inbounds i32, i32* %0, i64 1
   %ret2 = getelementptr inbounds i32, i32* %1, i64 2
   %ret = select i1 %2, i32* %ret1, i32* %ret2

Modified: llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll?rev=369328&r1=369327&r2=369328&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll Mon Aug 19 23:02:39 2019
@@ -82,7 +82,7 @@ declare i8* @baz(...) nounwind uwtable
 ; FIXME: Until we have "on-demand" attribute generation we do not determine the
 ;        alignment for the return value here.
 ;        define nonnull align 8 dereferenceable(8) i8** @getter()
-; CHECK: define nonnull dereferenceable(8) i8** @getter()
+; CHECK: define dereferenceable_or_null(8) i8** @getter()
 define i8** @getter() {
   ret i8** @G
 }
@@ -91,7 +91,7 @@ define i8** @getter() {
 ;        alignment for the return value here.
 ; Returning global pointer. Should not be noalias.
 ;        define nonnull align 8 dereferenceable(8) i8** @calle1()
-; CHECK: define nonnull dereferenceable(8) i8** @calle1()
+; CHECK: define dereferenceable_or_null(8) i8** @calle1()
 define i8** @calle1(){
   %1 = call i8** @getter()
   ret i8** %1

Modified: llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll?rev=369328&r1=369327&r2=369328&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll Mon Aug 19 23:02:39 2019
@@ -8,13 +8,18 @@ declare nonnull i8* @ret_nonnull()
 
 ; Return a pointer trivially nonnull (call return attribute)
 define i8* @test1() {
-; BOTH: define nonnull i8* @test1
+; FIXME: Until we have "on-demand" attribute generation we do not determine the
+;        return value properties.
+; FNATTR: define nonnull i8* @test1
+; ATTRIBUTOR: define i8* @test1
   %ret = call i8* @ret_nonnull()
   ret i8* %ret
 }
 
 ; Return a pointer trivially nonnull (argument attribute)
 define i8* @test2(i8* nonnull %p) {
+; FIXME: Until we have "on-demand" attribute generation we do not determine the
+;        return value properties.
 ; BOTH: define nonnull i8* @test2
   ret i8* %p
 }
@@ -33,7 +38,10 @@ end:
 }
 
 define i8* @test3(i1 %c) {
-; BOTH: define nonnull i8* @test3
+; FIXME: Until we have "on-demand" attribute generation we do not determine the
+;        return value properties.
+; FNATTR: define nonnull i8* @test3
+; ATTRIBUTOR: define i8* @test3
   call i8* @scc_binder(i1 %c)
   %ret = call i8* @ret_nonnull()
   ret i8* %ret
@@ -79,7 +87,10 @@ define i8* @test5(i1 %c) {
 ; Local analysis, but going through a self recursive phi
 define i8* @test6() {
 entry:
-; BOTH: define nonnull i8* @test6
+; FIXME: Until we have "on-demand" attribute generation we do not determine the
+;        return value properties.
+; FNATTR: define nonnull i8* @test6
+; ATTRIBUTOR: define i8* @test6
   %ret = call i8* @ret_nonnull()
   br label %loop
 loop:
@@ -95,7 +106,10 @@ define i8* @test7(i8* %a) {
   ret i8* %b
 }
 
-; BOTH: define nonnull i8* @test8
+; FIXME: Until we have "on-demand" attribute generation we do not determine the
+;        return value properties.
+; FNATTR: define nonnull i8* @test8
+; ATTRIBUTOR: define i8* @test8
 define i8* @test8(i8* %a) {
   %b = getelementptr inbounds i8, i8* %a, i64 1
   ret i8* %b
@@ -179,7 +193,7 @@ declare nonnull i8* @nonnull()
 
 define internal i32* @f1(i32* %arg) {
 ; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull %arg)
-; ATTRIBUTOR: define internal nonnull i32* @f1(i32* %arg)
+; ATTRIBUTOR: define internal i32* @f1(i32* %arg)
 
 bb:
   %tmp = icmp eq i32* %arg, null
@@ -209,7 +223,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 i32* @f2(i32* %arg)
 bb:
 
 ; FIXME: missing nonnull. It should be @f1(i32* nonnull %arg) 
@@ -429,7 +443,10 @@ exc:
   unreachable
 }
 
-; BOTH: define nonnull i32* @gep1(
+; FIXME: Until we have "on-demand" attribute generation we do not determine the
+;        return value properties.
+; FNATTR:     define nonnull i32* @gep1(
+; ATTRIBUTOR: define i32* @gep1(
 define i32* @gep1(i32* %p) {
   %q = getelementptr inbounds i32, i32* %p, i32 1
   ret i32* %q
@@ -448,7 +465,10 @@ define i32 addrspace(3)* @gep2(i32 addrs
   ret i32 addrspace(3)* %q
 }
 
-; BOTH: define internal nonnull i32* @g2()
+; FIXME: Until we have "on-demand" attribute generation we do not determine the
+;        return value properties.
+; FNATTR: define internal nonnull i32* @g2()
+; ATTRIBUTOR: define internal i32* @g2()
 define internal i32* @g2() {
   ret i32* inttoptr (i64 4 to i32*)
 }

Modified: llvm/trunk/test/Transforms/FunctionAttrs/noreturn_async.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/noreturn_async.ll?rev=369328&r1=369327&r2=369328&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/noreturn_async.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/noreturn_async.ll Mon Aug 19 23:02:39 2019
@@ -83,7 +83,7 @@ entry:
 ; CHECK-NOT:  nounwind
 ; CHECK-NEXT: define
 ; CHECK-NEXT:   entry:
-; CHECK-NEXT:   %call3 = call i32 (i8*, ...) @printf(i8* dereferenceable_or_null(18) getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C at _0BC@NKPAGFFJ at Exception?5caught?6?$AA@", i64 0, i64 0))
+; CHECK-NEXT:   %call3 = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(18) getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C at _0BC@NKPAGFFJ at Exception?5caught?6?$AA@", i64 0, i64 0))
 ; CHECK-NEXT:   call void @"?overflow@@YAXXZ_may_throw"()
 ; CHECK-NEXT:   unreachable
   %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C at _0BC@NKPAGFFJ at Exception?5caught?6?$AA@", i64 0, i64 0))

Modified: llvm/trunk/test/Transforms/FunctionAttrs/noreturn_sync.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/noreturn_sync.ll?rev=369328&r1=369327&r2=369328&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/noreturn_sync.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/noreturn_sync.ll Mon Aug 19 23:02:39 2019
@@ -79,7 +79,7 @@ entry:
 ; CHECK-NOT:  nounwind
 ; CHECK-NEXT: define
 ; CHECK-NEXT:   entry:
-; CHECK-NEXT:   %call3 = call i32 (i8*, ...) @printf(i8* dereferenceable_or_null(18) getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C at _0BC@NKPAGFFJ at Exception?5caught?6?$AA@", i64 0, i64 0))
+; CHECK-NEXT:   %call3 = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(18) getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C at _0BC@NKPAGFFJ at Exception?5caught?6?$AA@", i64 0, i64 0))
 ; CHECK-NEXT:   call void @"?overflow@@YAXXZ_may_throw"()
 ; CHECK-NEXT:   unreachable
   %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C at _0BC@NKPAGFFJ at Exception?5caught?6?$AA@", i64 0, i64 0))

Modified: llvm/trunk/test/Transforms/FunctionAttrs/nosync.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/nosync.ll?rev=369328&r1=369327&r2=369328&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/nosync.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/nosync.ll Mon Aug 19 23:02:39 2019
@@ -27,8 +27,11 @@ target datalayout = "e-m:e-i64:64-f80:12
 
 ; FNATTR: Function Attrs: norecurse nounwind optsize readnone ssp uwtable
 ; FNATTR-NEXT: define nonnull i32* @foo(%struct.ST* readnone %s)
+; FIXME: Until we have "on-demand" attribute generation we do not determine the
+;        return value properties.
 ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
-; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* %s)
+;                  define nonnull i32* @foo(%struct.ST* %s)
+; ATTRIBUTOR-NEXT: define i32* @foo(%struct.ST* %s)
 define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
 entry:
   %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13




More information about the llvm-commits mailing list