[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-09-03 Thread Johannes Doerfert via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
jdoerfert marked an inline comment as done.
Closed by commit rL370817: [Attributor] Deduce no-capture argument 
attribute (authored by jdoerfert, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D59922?vs=218109=218528#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  llvm/trunk/include/llvm/Transforms/IPO/Attributor.h
  llvm/trunk/lib/Transforms/IPO/Attributor.cpp
  llvm/trunk/test/Transforms/FunctionAttrs/align.ll
  llvm/trunk/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/trunk/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/trunk/test/Transforms/FunctionAttrs/dereferenceable.ll
  llvm/trunk/test/Transforms/FunctionAttrs/internal-noalias.ll
  llvm/trunk/test/Transforms/FunctionAttrs/liveness.ll
  llvm/trunk/test/Transforms/FunctionAttrs/noalias_returned.ll
  llvm/trunk/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/trunk/test/Transforms/FunctionAttrs/nonnull.ll
  llvm/trunk/test/Transforms/FunctionAttrs/nosync.ll
  llvm/trunk/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll

Index: llvm/trunk/include/llvm/Transforms/IPO/Attributor.h
===
--- llvm/trunk/include/llvm/Transforms/IPO/Attributor.h
+++ llvm/trunk/include/llvm/Transforms/IPO/Attributor.h
@@ -270,6 +270,25 @@
   }
   ///}
 
+  /// Return the associated argument, if any.
+  ///
+  ///{
+  Argument *getAssociatedArgument() {
+if (auto *Arg = dyn_cast(()))
+  return Arg;
+int ArgNo = getArgNo();
+if (ArgNo < 0)
+  return nullptr;
+Function *AssociatedFn = getAssociatedFunction();
+if (!AssociatedFn || AssociatedFn->arg_size() <= unsigned(ArgNo))
+  return nullptr;
+return AssociatedFn->arg_begin() + ArgNo;
+  }
+  const Argument *getAssociatedArgument() const {
+return const_cast(this)->getAssociatedArgument();
+  }
+  ///}
+
   /// Return the Function surrounding the anchor value.
   ///
   ///{
@@ -1549,6 +1568,56 @@
   static const char ID;
 };
 
+/// An abstract interface for all nocapture attributes.
+struct AANoCapture
+: public IRAttribute> {
+  AANoCapture(const IRPosition ) : IRAttribute(IRP) {}
+
+  /// State encoding bits. A set bit in the state means the property holds.
+  /// NO_CAPTURE is the best possible state, 0 the worst possible state.
+  enum {
+NOT_CAPTURED_IN_MEM = 1 << 0,
+NOT_CAPTURED_IN_INT = 1 << 1,
+NOT_CAPTURED_IN_RET = 1 << 2,
+
+/// If we do not capture the value in memory or through integers we can only
+/// communicate it back as a derived pointer.
+NO_CAPTURE_MAYBE_RETURNED = NOT_CAPTURED_IN_MEM | NOT_CAPTURED_IN_INT,
+
+/// If we do not capture the value in memory, through integers, or as a
+/// derived pointer we know it is not captured.
+NO_CAPTURE =
+NOT_CAPTURED_IN_MEM | NOT_CAPTURED_IN_INT | NOT_CAPTURED_IN_RET,
+  };
+
+  /// Return true if we know that the underlying value is not captured in its
+  /// respective scope.
+  bool isKnownNoCapture() const { return isKnown(NO_CAPTURE); }
+
+  /// Return true if we assume that the underlying value is not captured in its
+  /// respective scope.
+  bool isAssumedNoCapture() const { return isAssumed(NO_CAPTURE); }
+
+  /// Return true if we know that the underlying value is not captured in its
+  /// respective scope but we allow it to escape through a "return".
+  bool isKnownNoCaptureMaybeReturned() const {
+return isKnown(NO_CAPTURE_MAYBE_RETURNED);
+  }
+
+  /// Return true if we assume that the underlying value is not captured in its
+  /// respective scope but we allow it to escape through a "return".
+  bool isAssumedNoCaptureMaybeReturned() const {
+return isAssumed(NO_CAPTURE_MAYBE_RETURNED);
+  }
+
+  /// Create an abstract attribute view for the position \p IRP.
+  static AANoCapture (const IRPosition , Attributor );
+
+  /// Unique ID (due to the unique address)
+  static const char ID;
+};
+
 } // end namespace llvm
 
 #endif // LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
Index: llvm/trunk/test/Transforms/FunctionAttrs/internal-noalias.ll
===
--- llvm/trunk/test/Transforms/FunctionAttrs/internal-noalias.ll
+++ llvm/trunk/test/Transforms/FunctionAttrs/internal-noalias.ll
@@ -10,7 +10,7 @@
 
 ; FIXME: Should be something like this.
 ; define internal i32 @noalias_args(i32* nocapture readonly %A, i32* noalias nocapture readonly %B)
-; CHECK: define internal i32 @noalias_args(i32* %A, i32* %B)
+; CHECK: define internal i32 @noalias_args(i32* nocapture %A, i32* nocapture %B)
 
 define internal i32 @noalias_args(i32* %A, i32* %B) #0 {
 entry:
@@ -25,7 +25,7 @@
 
 ; FIXME: Should be something like this.
 ; define internal i32 @noalias_args_argmem(i32* noalias nocapture readonly %A, i32* noalias nocapture readonly %B)
-; CHECK: define 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-09-03 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert marked 6 inline comments as done.
jdoerfert added inline comments.



Comment at: llvm/lib/Transforms/IPO/Attributor.cpp:2618
+else
+  Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
+  }

uenoku wrote:
> Maybe we need an exact definition for `no-capture-maybe-returned` in LangRef.
I add a flag to disable manifestation in non-testing modes. If we add users we 
can add it as a enum attribute, for now it is internal.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-09-02 Thread Hideto Ueno via Phabricator via cfe-commits
uenoku accepted this revision.
uenoku added a comment.
This revision is now accepted and ready to land.

I think the logic is sound. It looks good to me.




Comment at: llvm/lib/Transforms/IPO/Attributor.cpp:2618
+else
+  Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
+  }

Maybe we need an exact definition for `no-capture-maybe-returned` in LangRef.



Comment at: llvm/lib/Transforms/IPO/Attributor.cpp:2674
+  /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
+  /// set. All values in \p PotentialCopies are later tracked aswell. For every
+  /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,

aswell



Comment at: llvm/lib/Transforms/IPO/Attributor.cpp:2761
+  /// Register \p CS as potential copy of the value we are checking.
+  void addPotentialCopyIfNecessary(CallSite CS) {
+PotentialCopies.push_back(CS.getInstruction());

Why `IfNecessary`? It seems there is no check.



Comment at: llvm/lib/Transforms/IPO/Attributor.cpp:2819
+
+  AAAlign::StateType T;
+  // TODO: Once we have memory behavior attributes we should use them here

Align?



Comment at: llvm/lib/Transforms/IPO/Attributor.cpp:2864
+// TODO: Once we have call site specific value information we can provide
+//   call site specific liveness liveness information and then it makes
+//   sense to specialize attributes for call sites arguments instead of

liveness liveness


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-08-30 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 218109.
jdoerfert added a comment.

Update tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/align.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/dereferenceable.ll
  llvm/test/Transforms/FunctionAttrs/internal-noalias.ll
  llvm/test/Transforms/FunctionAttrs/liveness.ll
  llvm/test/Transforms/FunctionAttrs/noalias_returned.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/FunctionAttrs/nonnull.ll
  llvm/test/Transforms/FunctionAttrs/nosync.ll
  llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll

Index: llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
===
--- llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
@@ -102,7 +102,7 @@
 }
 
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind
-; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned %w0)
+; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned "no-capture-maybe-returned" %w0)
 define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
 entry:
   %tobool = icmp ne i32* %n0, null
Index: llvm/test/Transforms/FunctionAttrs/nosync.ll
===
--- llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ llvm/test/Transforms/FunctionAttrs/nosync.ll
@@ -28,7 +28,7 @@
 ; FNATTR: Function Attrs: norecurse nounwind optsize readnone ssp uwtable
 ; FNATTR-NEXT: define nonnull i32* @foo(%struct.ST* readnone %s)
 ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
-; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* %s)
+; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* "no-capture-maybe-returned" %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
@@ -186,7 +186,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define i32 @scc1(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define i32 @scc1(i32* %0)
+; ATTRIBUTOR-NEXT: define i32 @scc1(i32* nocapture %0)
 define i32 @scc1(i32* %0) noinline nounwind uwtable {
   tail call void @scc2(i32* %0);
   %val = tail call i32 @volatile_load(i32* %0);
@@ -196,7 +196,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define void @scc2(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define void @scc2(i32* %0)
+; ATTRIBUTOR-NEXT: define void @scc2(i32* nocapture %0)
 define void @scc2(i32* %0) noinline nounwind uwtable {
   tail call i32 @scc1(i32* %0);
   ret void;
@@ -224,7 +224,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @foo1(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence release
@@ -236,7 +236,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @bar(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @bar(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @bar(i32* %0, %"struct.std::atomic"* %1) {
   %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
   br label %4
@@ -256,7 +256,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR: Function Attrs: nofree nosync
-; ATTRIBUTOR: define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence syncscope("singlethread") release
@@ -268,7 +268,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar_singlethread(i32* nocapture 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-08-26 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 217306.
jdoerfert added a comment.

rebase and update tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/align.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/dereferenceable.ll
  llvm/test/Transforms/FunctionAttrs/liveness.ll
  llvm/test/Transforms/FunctionAttrs/noalias_returned.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/FunctionAttrs/nonnull.ll
  llvm/test/Transforms/FunctionAttrs/nosync.ll
  llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll

Index: llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
===
--- llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
@@ -102,7 +102,7 @@
 }
 
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind
-; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned %w0)
+; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned "no-capture-maybe-returned" %w0)
 define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
 entry:
   %tobool = icmp ne i32* %n0, null
Index: llvm/test/Transforms/FunctionAttrs/nosync.ll
===
--- llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ llvm/test/Transforms/FunctionAttrs/nosync.ll
@@ -28,7 +28,7 @@
 ; FNATTR: Function Attrs: norecurse nounwind optsize readnone ssp uwtable
 ; FNATTR-NEXT: define nonnull i32* @foo(%struct.ST* readnone %s)
 ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
-; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* %s)
+; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* "no-capture-maybe-returned" %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
@@ -186,7 +186,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define i32 @scc1(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define i32 @scc1(i32* %0)
+; ATTRIBUTOR-NEXT: define i32 @scc1(i32* nocapture %0)
 define i32 @scc1(i32* %0) noinline nounwind uwtable {
   tail call void @scc2(i32* %0);
   %val = tail call i32 @volatile_load(i32* %0);
@@ -196,7 +196,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define void @scc2(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define void @scc2(i32* %0)
+; ATTRIBUTOR-NEXT: define void @scc2(i32* nocapture %0)
 define void @scc2(i32* %0) noinline nounwind uwtable {
   tail call i32 @scc1(i32* %0);
   ret void;
@@ -224,7 +224,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @foo1(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence release
@@ -236,7 +236,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @bar(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @bar(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @bar(i32* %0, %"struct.std::atomic"* %1) {
   %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
   br label %4
@@ -256,7 +256,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR: Function Attrs: nofree nosync
-; ATTRIBUTOR: define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence syncscope("singlethread") release
@@ -268,7 +268,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar_singlethread(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-08-16 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 215716.
jdoerfert added a comment.

Add tests accidentally removed


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/align.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/dereferenceable.ll
  llvm/test/Transforms/FunctionAttrs/noalias_returned.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/FunctionAttrs/nonnull.ll
  llvm/test/Transforms/FunctionAttrs/nosync.ll
  llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll

Index: llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
===
--- llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
@@ -103,7 +103,7 @@
 }
 
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind
-; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned %w0)
+; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned "no-capture-maybe-returned" %w0)
 define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
 entry:
   %tobool = icmp ne i32* %n0, null
Index: llvm/test/Transforms/FunctionAttrs/nosync.ll
===
--- llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ llvm/test/Transforms/FunctionAttrs/nosync.ll
@@ -28,7 +28,7 @@
 ; FNATTR: Function Attrs: norecurse nounwind optsize readnone ssp uwtable
 ; FNATTR-NEXT: define nonnull i32* @foo(%struct.ST* readnone %s)
 ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
-; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* %s)
+; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* "no-capture-maybe-returned" %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
@@ -186,7 +186,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define i32 @scc1(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define i32 @scc1(i32* %0)
+; ATTRIBUTOR-NEXT: define i32 @scc1(i32* nocapture %0)
 define i32 @scc1(i32* %0) noinline nounwind uwtable {
   tail call void @scc2(i32* %0);
   %val = tail call i32 @volatile_load(i32* %0);
@@ -196,7 +196,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define void @scc2(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define void @scc2(i32* %0)
+; ATTRIBUTOR-NEXT: define void @scc2(i32* nocapture %0)
 define void @scc2(i32* %0) noinline nounwind uwtable {
   tail call i32 @scc1(i32* %0);
   ret void;
@@ -224,7 +224,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @foo1(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence release
@@ -236,7 +236,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @bar(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @bar(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @bar(i32* %0, %"struct.std::atomic"* %1) {
   %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
   br label %4
@@ -256,7 +256,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR: Function Attrs: nofree nosync
-; ATTRIBUTOR: define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence syncscope("singlethread") release
@@ -268,7 +268,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar_singlethread(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
 ; ATTRIBUTOR: Function 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-08-16 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 215713.
jdoerfert added a comment.

Add more test coverage and improve capture information based on 
dereferenceability


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/align.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/dereferenceable.ll
  llvm/test/Transforms/FunctionAttrs/noalias_returned.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/FunctionAttrs/nonnull.ll
  llvm/test/Transforms/FunctionAttrs/nosync.ll
  llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll

Index: llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
===
--- llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
@@ -103,7 +103,7 @@
 }
 
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind
-; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned %w0)
+; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned "no-capture-maybe-returned" %w0)
 define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
 entry:
   %tobool = icmp ne i32* %n0, null
Index: llvm/test/Transforms/FunctionAttrs/nosync.ll
===
--- llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ llvm/test/Transforms/FunctionAttrs/nosync.ll
@@ -28,7 +28,7 @@
 ; FNATTR: Function Attrs: norecurse nounwind optsize readnone ssp uwtable
 ; FNATTR-NEXT: define nonnull i32* @foo(%struct.ST* readnone %s)
 ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
-; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* %s)
+; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* "no-capture-maybe-returned" %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
@@ -186,7 +186,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define i32 @scc1(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define i32 @scc1(i32* %0)
+; ATTRIBUTOR-NEXT: define i32 @scc1(i32* nocapture %0)
 define i32 @scc1(i32* %0) noinline nounwind uwtable {
   tail call void @scc2(i32* %0);
   %val = tail call i32 @volatile_load(i32* %0);
@@ -196,7 +196,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define void @scc2(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define void @scc2(i32* %0)
+; ATTRIBUTOR-NEXT: define void @scc2(i32* nocapture %0)
 define void @scc2(i32* %0) noinline nounwind uwtable {
   tail call i32 @scc1(i32* %0);
   ret void;
@@ -224,7 +224,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @foo1(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence release
@@ -236,7 +236,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @bar(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @bar(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @bar(i32* %0, %"struct.std::atomic"* %1) {
   %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
   br label %4
@@ -256,7 +256,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR: Function Attrs: nofree nosync
-; ATTRIBUTOR: define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence syncscope("singlethread") release
@@ -268,7 +268,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar_singlethread(i32* nocapture readnone %0, %"struct.std::atomic"* 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-08-15 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 215504.
jdoerfert added a comment.

Extracted CaptureTracking changes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/align.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/dereferenceable.ll
  llvm/test/Transforms/FunctionAttrs/noalias_returned.ll
  llvm/test/Transforms/FunctionAttrs/nonnull.ll
  llvm/test/Transforms/FunctionAttrs/nosync.ll
  llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll

Index: llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
===
--- llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
@@ -103,7 +103,7 @@
 }
 
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind
-; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned %w0)
+; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned "no-capture-maybe-returned" %w0)
 define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
 entry:
   %tobool = icmp ne i32* %n0, null
Index: llvm/test/Transforms/FunctionAttrs/nosync.ll
===
--- llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ llvm/test/Transforms/FunctionAttrs/nosync.ll
@@ -28,7 +28,7 @@
 ; FNATTR: Function Attrs: norecurse nounwind optsize readnone ssp uwtable
 ; FNATTR-NEXT: define nonnull i32* @foo(%struct.ST* readnone %s)
 ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
-; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* %s)
+; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* "no-capture-maybe-returned" %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
@@ -186,7 +186,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define i32 @scc1(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define i32 @scc1(i32* %0)
+; ATTRIBUTOR-NEXT: define i32 @scc1(i32* nocapture %0)
 define i32 @scc1(i32* %0) noinline nounwind uwtable {
   tail call void @scc2(i32* %0);
   %val = tail call i32 @volatile_load(i32* %0);
@@ -196,7 +196,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define void @scc2(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define void @scc2(i32* %0)
+; ATTRIBUTOR-NEXT: define void @scc2(i32* nocapture %0)
 define void @scc2(i32* %0) noinline nounwind uwtable {
   tail call i32 @scc1(i32* %0);
   ret void;
@@ -224,7 +224,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @foo1(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence release
@@ -236,7 +236,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @bar(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @bar(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @bar(i32* %0, %"struct.std::atomic"* %1) {
   %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
   br label %4
@@ -256,7 +256,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR: Function Attrs: nofree nosync
-; ATTRIBUTOR: define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence syncscope("singlethread") release
@@ -268,7 +268,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar_singlethread(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
 ; ATTRIBUTOR: Function Attrs: nofree nosync
-; ATTRIBUTOR: define void 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-08-15 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 215498.
jdoerfert added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Analysis/CaptureTracking.cpp
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/align.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/dereferenceable.ll
  llvm/test/Transforms/FunctionAttrs/noalias_returned.ll
  llvm/test/Transforms/FunctionAttrs/nonnull.ll
  llvm/test/Transforms/FunctionAttrs/nosync.ll
  llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll

Index: llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
===
--- llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
@@ -103,7 +103,7 @@
 }
 
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind
-; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned %w0)
+; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned "no-capture-maybe-returned" %w0)
 define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
 entry:
   %tobool = icmp ne i32* %n0, null
Index: llvm/test/Transforms/FunctionAttrs/nosync.ll
===
--- llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ llvm/test/Transforms/FunctionAttrs/nosync.ll
@@ -28,7 +28,7 @@
 ; FNATTR: Function Attrs: norecurse nounwind optsize readnone ssp uwtable
 ; FNATTR-NEXT: define nonnull i32* @foo(%struct.ST* readnone %s)
 ; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
-; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* %s)
+; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* "no-capture-maybe-returned" %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
@@ -186,7 +186,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define i32 @scc1(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define i32 @scc1(i32* %0)
+; ATTRIBUTOR-NEXT: define i32 @scc1(i32* nocapture %0)
 define i32 @scc1(i32* %0) noinline nounwind uwtable {
   tail call void @scc2(i32* %0);
   %val = tail call i32 @volatile_load(i32* %0);
@@ -196,7 +196,7 @@
 ; FNATTR: Function Attrs: nofree noinline nounwind uwtable
 ; FNATTR-NEXT: define void @scc2(i32* %0)
 ; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define void @scc2(i32* %0)
+; ATTRIBUTOR-NEXT: define void @scc2(i32* nocapture %0)
 define void @scc2(i32* %0) noinline nounwind uwtable {
   tail call i32 @scc1(i32* %0);
   ret void;
@@ -224,7 +224,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @foo1(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence release
@@ -236,7 +236,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
 ; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @bar(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @bar(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @bar(i32* %0, %"struct.std::atomic"* %1) {
   %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
   br label %4
@@ -256,7 +256,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 ; ATTRIBUTOR: Function Attrs: nofree nosync
-; ATTRIBUTOR: define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1)
+; ATTRIBUTOR: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
 define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
   store i32 100, i32* %0, align 4
   fence syncscope("singlethread") release
@@ -268,7 +268,7 @@
 ; FNATTR: Function Attrs: nofree norecurse nounwind
 ; FNATTR-NEXT: define void @bar_singlethread(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
 ; ATTRIBUTOR: Function Attrs: nofree nosync
-; ATTRIBUTOR: 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-07-09 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 208811.
jdoerfert added a comment.
Herald added a subscriber: jfb.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/2009-01-02-LocalStores.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/convergent.ll
  llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/FunctionAttrs/nonnull.ll
  llvm/test/Transforms/FunctionAttrs/out-of-bounds-iterator-bug.ll
  llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
  llvm/test/Transforms/FunctionAttrs/readattrs.ll
  llvm/test/Transforms/FunctionAttrs/readnone.ll

Index: llvm/test/Transforms/FunctionAttrs/readnone.ll
===
--- llvm/test/Transforms/FunctionAttrs/readnone.ll
+++ llvm/test/Transforms/FunctionAttrs/readnone.ll
@@ -1,13 +1,17 @@
-; RUN: opt < %s -functionattrs -S | FileCheck %s
-; RUN: opt < %s -passes=function-attrs -S | FileCheck %s
+; RUN: opt < %s -attributor-disable=false -attributor -functionattrs -S | FileCheck %s
+; RUN: opt < %s -attributor-disable=false -passes="attributor,cgscc(function-attrs)" -S | FileCheck %s
 
-; CHECK: define void @bar(i8* nocapture readnone)
+; FIXME: Because nocapture and readnone deduction in the functionattrs pass are interleaved, it doesn't
+;trigger when nocapture is already present. Once the Attributor derives memory behavior,
+;this should be fixed.
+; FIXME: readnone missing for %0 two times
+; CHECK: define void @bar(i8* nocapture readonly)
 define void @bar(i8* readonly) {
   call void @foo(i8* %0)
 ret void
 }
 
-; CHECK: define void @foo(i8* nocapture readnone)
+; CHECK: define void @foo(i8* nocapture readonly)
 define void @foo(i8* readonly) {
   call void @bar(i8* %0)
   ret void
Index: llvm/test/Transforms/FunctionAttrs/readattrs.ll
===
--- llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -1,5 +1,5 @@
-; RUN: opt < %s -functionattrs -S | FileCheck %s
-; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs)' -S | FileCheck %s
+; RUN: opt < %s  -attributor -attributor-disable=false -functionattrs -S | FileCheck %s
+; RUN: opt < %s  -attributor-disable=false -aa-pipeline=basic-aa -passes='attributor,cgscc(function-attrs)' -S | FileCheck %s
 @x = global i32 0
 
 declare void @test1_1(i8* %x1_1, i8* readonly %y1_1, ...)
@@ -13,7 +13,7 @@
   ret void
 }
 
-; CHECK: define i8* @test2(i8* readnone returned %p)
+; CHECK: define i8* @test2(i8* readnone returned "no-capture-maybe-returned" %p)
 define i8* @test2(i8* %p) {
   store i32 0, i32* @x
   ret i8* %p
@@ -55,13 +55,13 @@
   ret void
 }
 
-; CHECK: define i32* @test8_1(i32* readnone returned %p)
+; CHECK: define i32* @test8_1(i32* readnone returned "no-capture-maybe-returned" %p)
 define i32* @test8_1(i32* %p) {
 entry:
   ret i32* %p
 }
 
-; CHECK: define void @test8_2(i32* %p)
+; CHECK: define void @test8_2(i32* nocapture %p)
 define void @test8_2(i32* %p) {
 entry:
   %call = call i32* @test8_1(i32* %p)
Index: llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
===
--- llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
@@ -1,5 +1,5 @@
-; RUN: opt -functionattrs -enable-nonnull-arg-prop -attributor -attributor-disable=false -S < %s | FileCheck %s
-; RUN: opt -functionattrs -enable-nonnull-arg-prop -attributor -attributor-disable=false -attributor-verify=true -S < %s | FileCheck %s
+; RUN: opt -attributor -functionattrs -enable-nonnull-arg-prop -attributor-disable=false -S < %s | FileCheck %s
+; RUN: opt -attributor -functionattrs -enable-nonnull-arg-prop -attributor-disable=false -attributor-verify=true -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
@@ -18,20 +18,23 @@
 ; as well as how the parameters are (transitively) used (n = readnone,
 ; r = readonly, w = writeonly).
 ;
-; What we should see is something along the lines of:
-;   1 - Number of functions marked as norecurse
-;   6 - Number of functions marked argmemonly
-;   6 - Number of functions marked as nounwind
-;  16 - Number of arguments marked nocapture
-;   4 - Number of arguments marked readnone
-;   6 - Number of arguments marked writeonly
-;   6 - Number of arguments marked readonly
-;   6 - Number of arguments 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-07-01 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert added a comment.

@hfinkel ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-04-01 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 193122.
jdoerfert added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  clang/test/CodeGenObjC/os_log.m
  clang/test/CodeGenOpenCL/as_type.cl
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/2009-01-02-LocalStores.ll
  llvm/test/Transforms/FunctionAttrs/SCC1.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/FunctionAttrs/readattrs.ll

Index: llvm/test/Transforms/FunctionAttrs/readattrs.ll
===
--- llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -13,7 +13,7 @@
   ret void
 }
 
-; CHECK: define i8* @test2(i8* readnone returned %p)
+; CHECK: define i8* @test2(i8* readnone returned "no-capture-maybe-returned" %p)
 define i8* @test2(i8* %p) {
   store i32 0, i32* @x
   ret i8* %p
@@ -55,13 +55,13 @@
   ret void
 }
 
-; CHECK: define i32* @test8_1(i32* readnone returned %p)
+; CHECK: define i32* @test8_1(i32* readnone returned "no-capture-maybe-returned" %p)
 define i32* @test8_1(i32* %p) {
 entry:
   ret i32* %p
 }
 
-; CHECK: define void @test8_2(i32* %p)
+; CHECK: define void @test8_2(i32* nocapture %p)
 define void @test8_2(i32* %p) {
 entry:
   %call = call i32* @test8_1(i32* %p)
Index: llvm/test/Transforms/FunctionAttrs/nocapture.ll
===
--- llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -1,9 +1,9 @@
 ; RUN: opt < %s -attributor -functionattrs -S | FileCheck %s
-; RUN: opt < %s -passes='attributor,cgscc(function-attrs)' -S | FileCheck %s
+; RUN: opt < %s -passes='cgscc(attributor,function-attrs)' -S | FileCheck %s
 
 @g = global i32* null		;  [#uses=1]
 
-; CHECK: define i32* @c1(i32* readnone returned %q)
+; CHECK: define i32* @c1(i32* readnone returned "no-capture-maybe-returned" %q)
 define i32* @c1(i32* %q) {
 	ret i32* %q
 }
@@ -134,7 +134,7 @@
 	ret void
 }
 
-; CHECK: define void @test1_1(i8* nocapture readnone %x1_1, i8* %y1_1)
+; CHECK: define void @test1_1(i8* nocapture %x1_1, i8* nocapture %y1_1)
 ; It would be acceptable to add readnone to %y1_1 and %y1_2.
 define void @test1_1(i8* %x1_1, i8* %y1_1) {
   call i8* @test1_2(i8* %x1_1, i8* %y1_1)
@@ -142,7 +142,7 @@
   ret void
 }
 
-; CHECK: define i8* @test1_2(i8* nocapture readnone %x1_2, i8* returned %y1_2)
+; CHECK: define i8* @test1_2(i8* nocapture %x1_2, i8* returned "no-capture-maybe-returned" %y1_2)
 define i8* @test1_2(i8* %x1_2, i8* %y1_2) {
   call void @test1_1(i8* %x1_2, i8* %y1_2)
   store i32* null, i32** @g
@@ -156,21 +156,21 @@
   ret void
 }
 
-; CHECK: define void @test3(i8* nocapture readnone %x3, i8* nocapture readnone %y3, i8* nocapture readnone %z3)
+; CHECK: define void @test3(i8* nocapture %x3, i8* nocapture readnone %y3, i8* nocapture %z3)
 define void @test3(i8* %x3, i8* %y3, i8* %z3) {
   call void @test3(i8* %z3, i8* %y3, i8* %x3)
   store i32* null, i32** @g
   ret void
 }
 
-; CHECK: define void @test4_1(i8* %x4_1)
+; CHECK: define void @test4_1(i8* nocapture readnone %x4_1)
 define void @test4_1(i8* %x4_1) {
   call i8* @test4_2(i8* %x4_1, i8* %x4_1, i8* %x4_1)
   store i32* null, i32** @g
   ret void
 }
 
-; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone returned %y4_2, i8* nocapture readnone %z4_2)
+; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone returned "no-capture-maybe-returned" %y4_2, i8* nocapture readnone %z4_2)
 define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2) {
   call void @test4_1(i8* null)
   store i32* null, i32** @g
Index: llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
===
--- llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
+++ llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
@@ -6,21 +6,21 @@
 
 ; Function Attrs: argmemonly
 define i32* @given_argmem_infer_readnone(i32* %p) #0 {
-; CHECK: define i32* @given_argmem_infer_readnone(i32* readnone returned %p) #0 {
+; CHECK: define i32* @given_argmem_infer_readnone(i32* readnone returned "no-capture-maybe-returned" %p) #0 {
 entry:
   ret i32* %p
 }
 
 ; Function Attrs: inaccessiblememonly
 define i32* @given_inaccessible_infer_readnone(i32* %p) #1 {
-; CHECK: define i32* @given_inaccessible_infer_readnone(i32* readnone returned %p) #0 {
+; CHECK: define i32* @given_inaccessible_infer_readnone(i32* readnone returned "no-capture-maybe-returned" %p) #0 {
 entry:
   ret i32* %p
 }
 
 ; Function Attrs: inaccessiblemem_or_argmemonly
 define i32* 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-03-30 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 192962.
jdoerfert added a comment.

Closed a side-channel through "integers"


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922

Files:
  clang/test/CodeGenObjC/os_log.m
  clang/test/CodeGenOpenCL/as_type.cl
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/2009-01-02-LocalStores.ll
  llvm/test/Transforms/FunctionAttrs/SCC1.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/FunctionAttrs/readattrs.ll

Index: llvm/test/Transforms/FunctionAttrs/readattrs.ll
===
--- llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -12,7 +12,7 @@
   ret void
 }
 
-; CHECK: define i8* @test2(i8* readnone returned %p)
+; CHECK: define i8* @test2(i8* readnone returned "no-capture-maybe-returned" %p)
 define i8* @test2(i8* %p) {
   store i32 0, i32* @x
   ret i8* %p
@@ -54,13 +54,13 @@
   ret void
 }
 
-; CHECK: define i32* @test8_1(i32* readnone returned %p)
+; CHECK: define i32* @test8_1(i32* readnone returned "no-capture-maybe-returned" %p)
 define i32* @test8_1(i32* %p) {
 entry:
   ret i32* %p
 }
 
-; CHECK: define void @test8_2(i32* %p)
+; CHECK: define void @test8_2(i32* nocapture %p)
 define void @test8_2(i32* %p) {
 entry:
   %call = call i32* @test8_1(i32* %p)
Index: llvm/test/Transforms/FunctionAttrs/nocapture.ll
===
--- llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -3,7 +3,7 @@
 
 @g = global i32* null		;  [#uses=1]
 
-; CHECK: define i32* @c1(i32* readnone returned %q)
+; CHECK: define i32* @c1(i32* readnone returned "no-capture-maybe-returned" %q)
 define i32* @c1(i32* %q) {
 	ret i32* %q
 }
@@ -134,7 +134,7 @@
 	ret void
 }
 
-; CHECK: define void @test1_1(i8* nocapture readnone %x1_1, i8* %y1_1)
+; CHECK: define void @test1_1(i8* nocapture %x1_1, i8* nocapture %y1_1)
 ; It would be acceptable to add readnone to %y1_1 and %y1_2.
 define void @test1_1(i8* %x1_1, i8* %y1_1) {
   call i8* @test1_2(i8* %x1_1, i8* %y1_1)
@@ -142,7 +142,7 @@
   ret void
 }
 
-; CHECK: define i8* @test1_2(i8* nocapture readnone %x1_2, i8* returned %y1_2)
+; CHECK: define i8* @test1_2(i8* nocapture %x1_2, i8* returned "no-capture-maybe-returned" %y1_2)
 define i8* @test1_2(i8* %x1_2, i8* %y1_2) {
   call void @test1_1(i8* %x1_2, i8* %y1_2)
   store i32* null, i32** @g
@@ -156,21 +156,21 @@
   ret void
 }
 
-; CHECK: define void @test3(i8* nocapture readnone %x3, i8* nocapture readnone %y3, i8* nocapture readnone %z3)
+; CHECK: define void @test3(i8* nocapture %x3, i8* nocapture readnone %y3, i8* nocapture %z3)
 define void @test3(i8* %x3, i8* %y3, i8* %z3) {
   call void @test3(i8* %z3, i8* %y3, i8* %x3)
   store i32* null, i32** @g
   ret void
 }
 
-; CHECK: define void @test4_1(i8* %x4_1)
+; CHECK: define void @test4_1(i8* nocapture readnone %x4_1)
 define void @test4_1(i8* %x4_1) {
   call i8* @test4_2(i8* %x4_1, i8* %x4_1, i8* %x4_1)
   store i32* null, i32** @g
   ret void
 }
 
-; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone returned %y4_2, i8* nocapture readnone %z4_2)
+; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone returned "no-capture-maybe-returned" %y4_2, i8* nocapture readnone %z4_2)
 define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2) {
   call void @test4_1(i8* null)
   store i32* null, i32** @g
Index: llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
===
--- llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
+++ llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
@@ -6,21 +6,21 @@
 
 ; Function Attrs: argmemonly
 define i32* @given_argmem_infer_readnone(i32* %p) #0 {
-; CHECK: define i32* @given_argmem_infer_readnone(i32* readnone returned %p) #0 {
+; CHECK: define i32* @given_argmem_infer_readnone(i32* readnone returned "no-capture-maybe-returned" %p) #0 {
 entry:
   ret i32* %p
 }
 
 ; Function Attrs: inaccessiblememonly
 define i32* @given_inaccessible_infer_readnone(i32* %p) #1 {
-; CHECK: define i32* @given_inaccessible_infer_readnone(i32* readnone returned %p) #0 {
+; CHECK: define i32* @given_inaccessible_infer_readnone(i32* readnone returned "no-capture-maybe-returned" %p) #0 {
 entry:
   ret i32* %p
 }
 
 ; Function Attrs: inaccessiblemem_or_argmemonly
 define i32* @given_inaccessible_or_argmem_infer_readnone(i32* %p) #2 {
-; CHECK: define i32* @given_inaccessible_or_argmem_infer_readnone(i32* readnone returned %p) #0 {
+; CHECK: define i32* 

[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-03-28 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert marked 2 inline comments as done.
jdoerfert added inline comments.



Comment at: llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll:103
-; FIXME: returned missing for %a
 ; FIXME: We should *not* derive any attributes for the return value not 
present on the argument!
 ; CHECK: define dso_local noalias nonnull i32* @srec16(i32* nocapture readnone 
%a)

The comments on this one were off from the very beginning, I'll fix them and 
there won't be a change during this commit.



Comment at: llvm/test/Transforms/FunctionAttrs/nocapture.ll:137
 
-; CHECK: define void @test1_1(i8* nocapture readnone %x1_1, i8* %y1_1)
 ; It would be acceptable to add readnone to %y1_1 and %y1_2.

So, the old FuncAttr deduction interleaves one of two memory behavior 
deductions with the capture analysis. With this patch capture analysis becomes 
obsolete, as the attributor added annotations, and certain memory behavior 
attributes are not detected anymore. There will be a memory behavior detection 
for the attributor soon which should make this problem go away.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59922/new/

https://reviews.llvm.org/D59922



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D59922: [Attributor] Deduce "no-capture" argument attribute

2019-03-28 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert created this revision.
jdoerfert added reviewers: homerdin, hfinkel, fedor.sergeev, sanjoy, spatel, 
nlopes, nicholas, reames.
Herald added subscribers: cfe-commits, bollu, hiraditya.
Herald added projects: clang, LLVM.

Add the no-capture argument attribute deduction to the Attributor
fixpoint framework.

The new string attributed "no-capture-maybe-returned" is introduced to
allow deduction of no-capture through functions that "capture" an
argument but only by "returning" it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D59922

Files:
  clang/test/CodeGenObjC/os_log.m
  clang/test/CodeGenOpenCL/as_type.cl
  llvm/include/llvm/Transforms/IPO/Attributor.h
  llvm/lib/Transforms/IPO/Attributor.cpp
  llvm/test/Transforms/FunctionAttrs/2009-01-02-LocalStores.ll
  llvm/test/Transforms/FunctionAttrs/SCC1.ll
  llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
  llvm/test/Transforms/FunctionAttrs/arg_returned.ll
  llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/FunctionAttrs/readattrs.ll

Index: llvm/test/Transforms/FunctionAttrs/readattrs.ll
===
--- llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -12,7 +12,7 @@
   ret void
 }
 
-; CHECK: define i8* @test2(i8* readnone returned %p)
+; CHECK: define i8* @test2(i8* readnone returned "no-capture-maybe-returned" %p)
 define i8* @test2(i8* %p) {
   store i32 0, i32* @x
   ret i8* %p
@@ -54,13 +54,13 @@
   ret void
 }
 
-; CHECK: define i32* @test8_1(i32* readnone returned %p)
+; CHECK: define i32* @test8_1(i32* readnone returned "no-capture-maybe-returned" %p)
 define i32* @test8_1(i32* %p) {
 entry:
   ret i32* %p
 }
 
-; CHECK: define void @test8_2(i32* %p)
+; CHECK: define void @test8_2(i32* nocapture %p)
 define void @test8_2(i32* %p) {
 entry:
   %call = call i32* @test8_1(i32* %p)
Index: llvm/test/Transforms/FunctionAttrs/nocapture.ll
===
--- llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -3,7 +3,7 @@
 
 @g = global i32* null		;  [#uses=1]
 
-; CHECK: define i32* @c1(i32* readnone returned %q)
+; CHECK: define i32* @c1(i32* readnone returned "no-capture-maybe-returned" %q)
 define i32* @c1(i32* %q) {
 	ret i32* %q
 }
@@ -134,7 +134,7 @@
 	ret void
 }
 
-; CHECK: define void @test1_1(i8* nocapture readnone %x1_1, i8* %y1_1)
+; CHECK: define void @test1_1(i8* nocapture %x1_1, i8* nocapture %y1_1)
 ; It would be acceptable to add readnone to %y1_1 and %y1_2.
 define void @test1_1(i8* %x1_1, i8* %y1_1) {
   call i8* @test1_2(i8* %x1_1, i8* %y1_1)
@@ -142,7 +142,7 @@
   ret void
 }
 
-; CHECK: define i8* @test1_2(i8* nocapture readnone %x1_2, i8* returned %y1_2)
+; CHECK: define i8* @test1_2(i8* nocapture %x1_2, i8* returned "no-capture-maybe-returned" %y1_2)
 define i8* @test1_2(i8* %x1_2, i8* %y1_2) {
   call void @test1_1(i8* %x1_2, i8* %y1_2)
   store i32* null, i32** @g
@@ -156,21 +156,21 @@
   ret void
 }
 
-; CHECK: define void @test3(i8* nocapture readnone %x3, i8* nocapture readnone %y3, i8* nocapture readnone %z3)
+; CHECK: define void @test3(i8* nocapture %x3, i8* nocapture readnone %y3, i8* nocapture %z3)
 define void @test3(i8* %x3, i8* %y3, i8* %z3) {
   call void @test3(i8* %z3, i8* %y3, i8* %x3)
   store i32* null, i32** @g
   ret void
 }
 
-; CHECK: define void @test4_1(i8* %x4_1)
+; CHECK: define void @test4_1(i8* nocapture readnone %x4_1)
 define void @test4_1(i8* %x4_1) {
   call i8* @test4_2(i8* %x4_1, i8* %x4_1, i8* %x4_1)
   store i32* null, i32** @g
   ret void
 }
 
-; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone returned %y4_2, i8* nocapture readnone %z4_2)
+; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone returned "no-capture-maybe-returned" %y4_2, i8* nocapture readnone %z4_2)
 define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2) {
   call void @test4_1(i8* null)
   store i32* null, i32** @g
Index: llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
===
--- llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
+++ llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
@@ -6,21 +6,21 @@
 
 ; Function Attrs: argmemonly
 define i32* @given_argmem_infer_readnone(i32* %p) #0 {
-; CHECK: define i32* @given_argmem_infer_readnone(i32* readnone returned %p) #0 {
+; CHECK: define i32* @given_argmem_infer_readnone(i32* readnone returned "no-capture-maybe-returned" %p) #0 {
 entry:
   ret i32* %p
 }
 
 ; Function Attrs: inaccessiblememonly
 define i32* @given_inaccessible_infer_readnone(i32* %p) #1 {
-; CHECK: define i32* @given_inaccessible_infer_readnone(i32* readnone returned %p) #0 {
+; CHECK: define i32* @given_inaccessible_infer_readnone(i32* readnone returned