[llvm] f549176 - [funcattrs] Add the maximal set of implied attributes to definitions

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 16 14:22:27 PDT 2021


Author: Philip Reames
Date: 2021-04-16T14:22:19-07:00
New Revision: f549176ad976caa3e19edd036df9a7e12770af7c

URL: https://github.com/llvm/llvm-project/commit/f549176ad976caa3e19edd036df9a7e12770af7c
DIFF: https://github.com/llvm/llvm-project/commit/f549176ad976caa3e19edd036df9a7e12770af7c.diff

LOG: [funcattrs] Add the maximal set of implied attributes to definitions

Have funcattrs expand all implied attributes into the IR. This expands the infrastructure from D100400, but for definitions not declarations this time.

Somewhat subtly, this mostly isn't semantic. Because the accessors did the inference, any client which used the accessor was already getting the stronger result. Clients that directly checked presence of attributes (there are some), will see a stronger result now.

The old behavior can end up quite confusing for two reasons:
* Without this change, we have situations where function-attrs appears to fail when inferring an attribute (as seen by a human reading IR), but that consuming code will see that it should have been implied. As a human trying to sanity check test results and study IR for optimization possibilities, this is exceeding error prone and confusing. (I'll note that I wasted several hours recently because of this.)
* We can have transforms which trigger without the IR appearing (on inspection) to meet the preconditions. This change doesn't prevent this from happening (as the accessors still involve multiple checks), but it should make it less frequent.

I'd argue in favor of deleting the extra checks out of the accessors after this lands, but I want that in it's own review as a) it's purely stylistic, and b) I already know there's some disagreement.

Once this lands, I'm also going to do a cleanup change which will delete some now redundant duplicate predicates in the inference code, but again, that deserves to be a change of it's own.

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

Added: 
    

Modified: 
    clang/test/CodeGenOpenCL/convergent.cl
    llvm/lib/Transforms/IPO/FunctionAttrs.cpp
    llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
    llvm/test/CodeGen/AMDGPU/inline-attr.ll
    llvm/test/Other/cgscc-devirt-iteration.ll
    llvm/test/Other/cgscc-iterate-function-mutation.ll
    llvm/test/Other/cgscc-observe-devirt.ll
    llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadOnly.ll
    llvm/test/Transforms/FunctionAttrs/atomic.ll
    llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
    llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll
    llvm/test/Transforms/FunctionAttrs/nofree.ll
    llvm/test/Transforms/FunctionAttrs/nosync.ll
    llvm/test/Transforms/FunctionAttrs/nounwind.ll
    llvm/test/Transforms/FunctionAttrs/optnone.ll
    llvm/test/Transforms/FunctionAttrs/willreturn-callsites.ll
    llvm/test/Transforms/FunctionAttrs/writeonly.ll
    llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
    llvm/test/Transforms/Inline/cgscc-update.ll

Removed: 
    


################################################################################
diff  --git a/clang/test/CodeGenOpenCL/convergent.cl b/clang/test/CodeGenOpenCL/convergent.cl
index 25951a64c1147..1905d7dd81aab 100644
--- a/clang/test/CodeGenOpenCL/convergent.cl
+++ b/clang/test/CodeGenOpenCL/convergent.cl
@@ -134,7 +134,7 @@ kernel void assume_convergent_asm()
   __asm__ volatile("s_barrier");
 }
 
-// CHECK: attributes #0 = { nofree noinline norecurse nounwind willreturn "
+// CHECK: attributes #0 = { nofree noinline norecurse nounwind willreturn mustprogress "
 // CHECK: attributes #1 = { {{[^}]*}}convergent{{[^}]*}} }
 // CHECK: attributes #2 = { {{[^}]*}}convergent{{[^}]*}} }
 // CHECK: attributes #3 = { {{[^}]*}}convergent noduplicate{{[^}]*}} }

diff  --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index cfd302a536c6f..0202046158b14 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -57,6 +57,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Utils/Local.h"
 #include <cassert>
 #include <iterator>
 #include <map>
@@ -1556,21 +1557,7 @@ static bool addNoSyncAttr(const SCCNodeSet &SCCNodes) {
         ++NumNoSync;
       },
       /* RequiresExactDefinition= */ true});
-  bool Changed = AI.run(SCCNodes);
-
-  // readnone + not convergent implies nosync
-  // (This is here so that we don't have to duplicate the function local
-  //  memory reasoning of the readnone analysis.)
-  for (Function *F : SCCNodes) {
-    if (!F || F->hasNoSync())
-      continue;
-    if (!F->doesNotAccessMemory() || F->isConvergent())
-      continue;
-    F->setNoSync();
-    NumNoSync++;
-    Changed = true;
-  }
-  return Changed;
+  return AI.run(SCCNodes);
 }
 
 static SCCNodesResult createSCCNodeSet(ArrayRef<Function *> Functions) {
@@ -1630,6 +1617,14 @@ static bool deriveAttrsInPostOrder(ArrayRef<Function *> Functions,
 
   Changed |= addNoSyncAttr(Nodes.SCCNodes);
 
+  // Finally, infer the maximal set of attributes from the ones we've inferred
+  // above.  This is handling the cases where one attribute on a signature
+  // implies another, but for implementation reasons the inference rule for
+  // the later is missing (or simply less sophisticated).
+  for (Function *F : Nodes.SCCNodes)
+    if (F)
+      Changed |= inferAttributesFromOthers(*F);
+
   return Changed;
 }
 

diff  --git a/llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll b/llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
index 61a46337898fe..06a3004dd8ee6 100644
--- a/llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
+++ b/llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
@@ -72,13 +72,13 @@ define i32 @test3_no(i8* %p) nounwind {
 declare void @callee(i32* %p) nounwind
 declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1) nounwind
 
-; CHECK: attributes #0 = { norecurse nosync nounwind readnone willreturn }
-; CHECK: attributes #1 = { nofree norecurse nosync nounwind willreturn writeonly }
-; CHECK: attributes #2 = { nounwind readonly }
+; CHECK: attributes #0 = { nofree norecurse nosync nounwind readnone willreturn mustprogress }
+; CHECK: attributes #1 = { nofree norecurse nosync nounwind willreturn  writeonly mustprogress }
+; CHECK: attributes #2 = { nofree nounwind readonly }
 ; CHECK: attributes #3 = { nounwind }
-; CHECK: attributes #4 = { nosync nounwind readnone willreturn }
-; CHECK: attributes #5 = { nofree nosync nounwind willreturn }
-; CHECK: attributes #6 = { nofree norecurse nosync nounwind willreturn }
+; CHECK: attributes #4 = { nofree nosync nounwind readnone willreturn mustprogress }
+; CHECK: attributes #5 = { nofree nosync nounwind willreturn mustprogress }
+; CHECK: attributes #6 = { nofree norecurse nosync nounwind willreturn mustprogress }
 ; CHECK: attributes #7 = { argmemonly nofree nosync nounwind willreturn }
 
 ; Root note.

diff  --git a/llvm/test/CodeGen/AMDGPU/inline-attr.ll b/llvm/test/CodeGen/AMDGPU/inline-attr.ll
index acf04a95db3c8..16e3e5c578feb 100644
--- a/llvm/test/CodeGen/AMDGPU/inline-attr.ll
+++ b/llvm/test/CodeGen/AMDGPU/inline-attr.ll
@@ -6,14 +6,14 @@
 ; GCN: define amdgpu_kernel void @caller(float addrspace(1)* nocapture %p) local_unnamed_addr #1 {
 ; GCN: %mul.i = fmul float %load, 1.500000e+01
 
-; UNSAFE: attributes #0 = { norecurse nosync nounwind readnone willreturn "unsafe-fp-math"="true" }
-; UNSAFE: attributes #1 = { nofree norecurse nosync nounwind willreturn "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="true" }
+; UNSAFE: attributes #0 = { nofree norecurse nosync nounwind readnone willreturn mustprogress "unsafe-fp-math"="true" }
+; UNSAFE: attributes #1 = { nofree norecurse nosync nounwind willreturn mustprogress "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="true" }
 
-; NOINFS: attributes #0 = { norecurse nosync nounwind readnone willreturn "no-infs-fp-math"="true" }
-; NOINFS: attributes #1 = { nofree norecurse nosync nounwind willreturn "less-precise-fpmad"="false" "no-infs-fp-math"="true" "no-nans-fp-math"="false" "unsafe-fp-math"="false" }
+; NOINFS: attributes #0 = { nofree norecurse nosync nounwind readnone willreturn mustprogress "no-infs-fp-math"="true" }
+; NOINFS: attributes #1 = { nofree norecurse nosync nounwind willreturn mustprogress "less-precise-fpmad"="false" "no-infs-fp-math"="true" "no-nans-fp-math"="false" "unsafe-fp-math"="false" }
 
-; NONANS: attributes #0 = { norecurse nosync nounwind readnone willreturn "no-nans-fp-math"="true" }
-; NONANS: attributes #1 = { nofree norecurse nosync nounwind willreturn "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="true" "unsafe-fp-math"="false" }
+; NONANS: attributes #0 = { nofree norecurse nosync nounwind readnone willreturn mustprogress "no-nans-fp-math"="true" }
+; NONANS: attributes #1 = { nofree norecurse nosync nounwind willreturn mustprogress "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="true" "unsafe-fp-math"="false" }
 
 define float @foo(float %x) #0 {
 entry:

diff  --git a/llvm/test/Other/cgscc-devirt-iteration.ll b/llvm/test/Other/cgscc-devirt-iteration.ll
index 092c624442db0..27892e85cec7a 100644
--- a/llvm/test/Other/cgscc-devirt-iteration.ll
+++ b/llvm/test/Other/cgscc-devirt-iteration.ll
@@ -28,7 +28,7 @@ declare void @unknown()
 
 define void @test1() {
 ; BEFORE-NOT: Function Attrs
-; AFTER: Function Attrs: nosync readnone
+; AFTER: Function Attrs: nofree nosync readnone
 ; CHECK-LABEL: define void @test1()
 entry:
   %fptr = alloca void ()*
@@ -56,8 +56,8 @@ declare void @readnone_with_arg(void ()**) readnone
 
 define void @test2_a(void ()** %ignore) {
 ; BEFORE-NOT: Function Attrs
-; AFTER1: Function Attrs: readonly
-; AFTER2: Function Attrs: nosync readnone
+; AFTER1: Function Attrs: nofree readonly
+; AFTER2: Function Attrs: nofree nosync readnone
 ; BEFORE: define void @test2_a(void ()** %ignore)
 ; AFTER: define void @test2_a(void ()** readnone %ignore)
 entry:
@@ -77,8 +77,8 @@ entry:
 
 define void @test2_b() {
 ; BEFORE-NOT: Function Attrs
-; AFTER1: Function Attrs: readonly
-; AFTER2: Function Attrs: nosync readnone
+; AFTER1: Function Attrs: nofree readonly
+; AFTER2: Function Attrs: nofree nosync readnone
 ; CHECK-LABEL: define void @test2_b()
 entry:
   %f2ptr = alloca void ()*

diff  --git a/llvm/test/Other/cgscc-iterate-function-mutation.ll b/llvm/test/Other/cgscc-iterate-function-mutation.ll
index 470f9055ced70..2075a06a756bc 100644
--- a/llvm/test/Other/cgscc-iterate-function-mutation.ll
+++ b/llvm/test/Other/cgscc-iterate-function-mutation.ll
@@ -1,8 +1,8 @@
 ; RUN: opt -aa-pipeline=basic-aa -passes='cgscc(function-attrs,function(simplify-cfg))' -S < %s | FileCheck %s
 
-declare void @readnone() nosync readnone
+declare void @readnone() nofree nosync readnone
 declare void @unknown()
-declare void @reference_function_pointer(void()*) nosync readnone
+declare void @reference_function_pointer(void()*) nofree nosync readnone
 
 ; The @test1_* set of functions checks that when we mutate functions with
 ; simplify-cfg to delete call edges and this ends up splitting both the SCCs
@@ -338,4 +338,4 @@ exit:
   ret void
 }
 
-; CHECK: attributes #0 = { nosync readnone }
+; CHECK: attributes #0 = { nofree nosync readnone }

diff  --git a/llvm/test/Other/cgscc-observe-devirt.ll b/llvm/test/Other/cgscc-observe-devirt.ll
index 67d630b23a332..6a6168ca49d4d 100644
--- a/llvm/test/Other/cgscc-observe-devirt.ll
+++ b/llvm/test/Other/cgscc-observe-devirt.ll
@@ -10,7 +10,7 @@
 ; without requiring the outer manager to iterate doesn't break any invariant.
 ; RUN: opt -aa-pipeline=basic-aa -passes='cgscc(function-attrs,function(gvn),function-attrs)' -S < %s | FileCheck %s --check-prefix=AFTER
 
-declare void @readnone() nosync readnone
+declare void @readnone() nofree nosync readnone
 declare void @unknown()
 
 ; The @test1_* checks that if we refine an indirect call to a direct call and
@@ -103,4 +103,4 @@ define void @test2_b3() {
   ret void
 }
 
-; CHECK: attributes #0 = { nosync readnone }
+; CHECK: attributes #0 = { nofree nosync readnone }

diff  --git a/llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadOnly.ll b/llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadOnly.ll
index 4ea6fdc87dfa3..cde17f48a0fe6 100644
--- a/llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadOnly.ll
+++ b/llvm/test/Transforms/FunctionAttrs/2008-09-03-ReadOnly.ll
@@ -8,7 +8,8 @@ entry:
   ret i32 %tmp
 }
 
-; CHECK: declare i32 @e() #0
+; CHECK: declare i32 @e() #1
 declare i32 @e() readonly
 
-; CHECK: attributes #0 = { readonly }
+; CHECK: attributes #0 = { nofree readonly }
+; CHECK: attributes #1 = { readonly }

diff  --git a/llvm/test/Transforms/FunctionAttrs/atomic.ll b/llvm/test/Transforms/FunctionAttrs/atomic.ll
index 3208595684fc7..d8f801081b7b9 100644
--- a/llvm/test/Transforms/FunctionAttrs/atomic.ll
+++ b/llvm/test/Transforms/FunctionAttrs/atomic.ll
@@ -20,5 +20,5 @@ entry:
   ret i32 %r
 }
 
-; CHECK: attributes #0 = { norecurse nosync nounwind readnone ssp uwtable willreturn }
-; CHECK: attributes #1 = { nofree norecurse nounwind ssp uwtable willreturn }
+; CHECK: attributes #0 = { nofree norecurse nosync nounwind readnone ssp uwtable willreturn mustprogress }
+; CHECK: attributes #1 = { nofree norecurse nounwind ssp uwtable willreturn mustprogress }

diff  --git a/llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll b/llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
index e913aca20c58e..d8e2db15691ac 100644
--- a/llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
+++ b/llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll
@@ -28,5 +28,5 @@ entry:
 attributes #0 = { argmemonly }
 attributes #1 = { inaccessiblememonly }
 attributes #2 = { inaccessiblemem_or_argmemonly }
-; CHECK: attributes #0 = { norecurse nosync nounwind readnone willreturn }
+; CHECK: attributes #0 = { nofree norecurse nosync nounwind readnone willreturn mustprogress }
 ; CHECK-NOT: attributes

diff  --git a/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll b/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll
index 73befa3a0a995..41c19870ba77c 100644
--- a/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll
@@ -12,7 +12,7 @@ declare void @_ZdaPv(i8*) local_unnamed_addr #2
 
 
 ; TEST 1 (positive case)
-; FNATTR: Function Attrs: noinline norecurse nosync nounwind readnone uwtable
+; FNATTR: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
 ; FNATTR-NEXT: define void @only_return()
 define void @only_return() #0 {
     ret void
@@ -78,14 +78,14 @@ end:
 ; }
 
 
-; FNATTR: Function Attrs: noinline nosync nounwind readnone uwtable
+; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
 ; FNATTR-NEXT: define void @mutual_recursion1()
 define void @mutual_recursion1() #0 {
   call void @mutual_recursion2()
   ret void
 }
 
-; FNATTR: Function Attrs: noinline nosync nounwind readnone uwtable
+; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
 ; FNATTR-NEXT: define void @mutual_recursion2()
 define void @mutual_recursion2() #0 {
   call void @mutual_recursion1()
@@ -132,7 +132,7 @@ define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr #0
 ; FNATTR-NEXT: declare void @nofree_function()
 declare void @nofree_function() nofree readnone #0
 
-; FNATTR: Function Attrs: noinline nosync nounwind readnone uwtable
+; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
 ; FNATTR-NEXT: define void @call_nofree_function()
 define void @call_nofree_function() #0 {
     tail call void @nofree_function()
@@ -168,7 +168,7 @@ define void @call_both() #0 {
 
 ; TEST 10 (positive case)
 ; Call intrinsic function
-; FNATTRS: Function Attrs: noinline nosync readnone speculatable
+; FNATTRS: Function Attrs: nofree noinline nosync readnone speculatable
 ; FNATTRS-NEXT: declare float @llvm.floor.f32(float %0)
 declare float @llvm.floor.f32(float)
 

diff  --git a/llvm/test/Transforms/FunctionAttrs/nofree.ll b/llvm/test/Transforms/FunctionAttrs/nofree.ll
index a51f8468a56e7..16e8bc25a5c3e 100644
--- a/llvm/test/Transforms/FunctionAttrs/nofree.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nofree.ll
@@ -36,7 +36,7 @@ entry:
 declare void @free(i8* nocapture) local_unnamed_addr #2
 
 define i32 @_Z4foo3Pi(i32* nocapture readonly %a) local_unnamed_addr #3 {
-; CHECK: Function Attrs: norecurse nosync nounwind readonly uwtable willreturn
+; CHECK: Function Attrs: nofree norecurse nosync nounwind readonly uwtable willreturn
 ; CHECK-LABEL: @_Z4foo3Pi(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4

diff  --git a/llvm/test/Transforms/FunctionAttrs/nosync.ll b/llvm/test/Transforms/FunctionAttrs/nosync.ll
index aed1f3669afc8..5247ac5fa90d4 100644
--- a/llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nosync.ll
@@ -6,7 +6,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
 ; Base case, empty function
 define void @test1() {
-; CHECK: Function Attrs: norecurse nosync nounwind readnone willreturn
+; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
 ; CHECK-LABEL: @test1(
 ; CHECK-NEXT:    ret void
 ;
@@ -15,7 +15,7 @@ define void @test1() {
 
 ; Show the bottom up walk
 define void @test2() {
-; CHECK: Function Attrs: norecurse nosync nounwind readnone willreturn
+; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:    call void @test1()
 ; CHECK-NEXT:    ret void
@@ -38,7 +38,7 @@ define void @test3() convergent {
 }
 
 define i32 @test4(i32 %a, i32 %b) {
-; CHECK: Function Attrs: norecurse nosync nounwind readnone willreturn
+; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
 ; CHECK-LABEL: @test4(
 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i32 [[A]]
@@ -137,7 +137,7 @@ define i32 @load_acquire(i32* nocapture readonly %0) norecurse nounwind uwtable
 }
 
 define i32 @load_unordered(i32* nocapture readonly %0) norecurse nounwind uwtable {
-; CHECK: Function Attrs: norecurse nosync nounwind readonly uwtable willreturn
+; CHECK: Function Attrs: nofree norecurse nosync nounwind readonly uwtable willreturn
 ; CHECK-LABEL: @load_unordered(
 ; CHECK-NEXT:    [[TMP2:%.*]] = load atomic i32, i32* [[TMP0:%.*]] unordered, align 4
 ; CHECK-NEXT:    ret i32 [[TMP2]]
@@ -271,7 +271,7 @@ declare void @readnone_test() convergent readnone
 
 ; negative. Convergent
 define void @convergent_readnone(){
-; CHECK: Function Attrs: nosync readnone
+; CHECK: Function Attrs: nofree nosync readnone
 ; CHECK-LABEL: @convergent_readnone(
 ; CHECK-NEXT:    call void @readnone_test()
 ; CHECK-NEXT:    ret void
@@ -299,7 +299,7 @@ define void @i_totally_sync() {
 declare float @llvm.cos(float %val) readnone
 
 define float @cos_test(float %x) {
-; CHECK: Function Attrs: nosync nounwind readnone willreturn
+; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn
 ; CHECK-LABEL: @cos_test(
 ; CHECK-NEXT:    [[C:%.*]] = call float @llvm.cos.f32(float [[X:%.*]])
 ; CHECK-NEXT:    ret float [[C]]

diff  --git a/llvm/test/Transforms/FunctionAttrs/nounwind.ll b/llvm/test/Transforms/FunctionAttrs/nounwind.ll
index 6a667cf73b1e7..02c1bb4fd1533 100644
--- a/llvm/test/Transforms/FunctionAttrs/nounwind.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nounwind.ll
@@ -1,14 +1,14 @@
 ; RUN: opt < %s -function-attrs -S | FileCheck %s
 
 ; TEST 1
-; CHECK: Function Attrs: norecurse nosync nounwind readnone
+; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone
 ; CHECK-NEXT: define i32 @foo1()
 define i32 @foo1() {
   ret i32 1
 }
 
 ; TEST 2
-; CHECK: Function Attrs: nosync nounwind readnone
+; CHECK: Function Attrs: nofree nosync nounwind readnone
 ; CHECK-NEXT: define i32 @scc1_foo()
 define i32 @scc1_foo() {
   %1 = call i32 @scc1_bar()
@@ -17,7 +17,7 @@ define i32 @scc1_foo() {
 
 
 ; TEST 3
-; CHECK: Function Attrs: nosync nounwind readnone
+; CHECK: Function Attrs: nofree nosync nounwind readnone
 ; CHECK-NEXT: define i32 @scc1_bar()
 define i32 @scc1_bar() {
   %1 = call i32 @scc1_foo()

diff  --git a/llvm/test/Transforms/FunctionAttrs/optnone.ll b/llvm/test/Transforms/FunctionAttrs/optnone.ll
index 850142762140a..57b9b82291dd8 100644
--- a/llvm/test/Transforms/FunctionAttrs/optnone.ll
+++ b/llvm/test/Transforms/FunctionAttrs/optnone.ll
@@ -20,6 +20,6 @@ declare i8 @strlen(i8*) noinline optnone
 ; CHECK: (i8*) #1
 
 ; CHECK-LABEL: attributes #0
-; CHECK: = { norecurse nosync nounwind readnone willreturn }
+; CHECK: = { nofree norecurse nosync nounwind readnone willreturn mustprogress }
 ; CHECK-LABEL: attributes #1
 ; CHECK: = { noinline optnone }

diff  --git a/llvm/test/Transforms/FunctionAttrs/willreturn-callsites.ll b/llvm/test/Transforms/FunctionAttrs/willreturn-callsites.ll
index 6c9cef7c9b6ec..10fd6930d4e58 100644
--- a/llvm/test/Transforms/FunctionAttrs/willreturn-callsites.ll
+++ b/llvm/test/Transforms/FunctionAttrs/willreturn-callsites.ll
@@ -38,7 +38,7 @@ define void @test_fn_willreturn(i32* %ptr) willreturn {
 }
 
 define void @test_fn_mustprogress_readonly_calls(i32* %ptr) mustprogress {
-; CHECK: Function Attrs: readonly willreturn mustprogress
+; CHECK: Function Attrs: nofree readonly willreturn mustprogress
 ; CHECK-LABEL: @test_fn_mustprogress_readonly_calls(
 ; CHECK-NOT:     call void @decl_readonly() #
 ; CHECK-NOT:     call void @decl_readnone() #

diff  --git a/llvm/test/Transforms/FunctionAttrs/writeonly.ll b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
index 1efea78ba1e34..1aaae3a275f6c 100644
--- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll
+++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
@@ -27,4 +27,4 @@ nouses-argworn-funwo_entry:
 
 ; CHECK: attributes #0 = { {{.*}} readnone {{.*}} }
 ; CHECK: attributes #1 = { {{.*}} readonly {{.*}} }
-; CHECK: attributes #2 = { {{.*}} writeonly }
+; CHECK: attributes #2 = { {{.*}} writeonly {{.*}} }

diff  --git a/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll b/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
index 6b50b4870c5d4..6b475103dadec 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
@@ -52,5 +52,5 @@ attributes #1 = { nounwind readnone speculatable }
 !28 = !DILocation(line: 9, column: 18, scope: !2)
 !29 = !DILocation(line: 10, column: 1, scope: !2)
 
-; CHECK: attributes #0 = { nofree norecurse nosync nounwind willreturn }
+; CHECK: attributes #0 = { nofree norecurse nosync nounwind willreturn mustprogress }
 ; CHECK-NOT: foo.coefficient1

diff  --git a/llvm/test/Transforms/Inline/cgscc-update.ll b/llvm/test/Transforms/Inline/cgscc-update.ll
index 024d57a13d8fc..5558e9b535ab2 100644
--- a/llvm/test/Transforms/Inline/cgscc-update.ll
+++ b/llvm/test/Transforms/Inline/cgscc-update.ll
@@ -27,7 +27,7 @@ entry:
 }
 
 ; This function should have had 'readnone' deduced for its SCC.
-; CHECK: Function Attrs: noinline nosync nounwind readnone
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone
 ; CHECK-NEXT: define void @test1_g()
 define void @test1_g() noinline {
 entry:
@@ -36,7 +36,7 @@ entry:
 }
 
 ; This function should have had 'readnone' deduced for its SCC.
-; CHECK: Function Attrs: noinline nosync nounwind readnone
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone
 ; CHECK-NEXT: define void @test1_h()
 define void @test1_h() noinline {
 entry:
@@ -59,7 +59,7 @@ entry:
 }
 
 ; This function should have had 'readnone' deduced for its SCC.
-; CHECK: Function Attrs: noinline nosync nounwind readnone
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone
 ; CHECK-NEXT: define void @test2_g()
 define void @test2_g() noinline {
 entry:
@@ -69,7 +69,7 @@ entry:
 }
 
 ; This function should have had 'readnone' deduced for its SCC.
-; CHECK: Function Attrs: noinline nosync nounwind readnone
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone
 ; CHECK-NEXT: define void @test2_h()
 define void @test2_h() noinline {
 entry:
@@ -152,7 +152,7 @@ exit:
 ; form a new SCC and should use that can deduce precise function attrs.
 
 ; This function should have had 'readnone' deduced for its SCC.
-; CHECK: Function Attrs: noinline nosync nounwind readnone
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone
 ; CHECK-NEXT: define void @test4_f1()
 define void @test4_f1() noinline {
 entry:
@@ -175,7 +175,7 @@ entry:
 }
 
 ; This function should have had 'readnone' deduced for its SCC.
-; CHECK: Function Attrs: noinline nosync nounwind readnone
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone
 ; CHECK-NEXT: define void @test4_h()
 define void @test4_h() noinline {
 entry:


        


More information about the llvm-commits mailing list