1 ; FIXME: convert CHECK-INDIRECT into CHECK (and remove -check-prefixes) as soon
2 ; FIXME: as new-pass-manager's handling of indirect_non_convergent_call is fixed
4 ; RUN: opt -functionattrs -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-INDIRECT
5 ; RUN: opt -passes=function-attrs -S < %s | FileCheck %s
7 ; CHECK: Function Attrs
8 ; CHECK-NOT: convergent
9 ; CHECK-NEXT: define i32 @nonleaf()
10 define i32 @nonleaf() convergent {
15 ; CHECK: Function Attrs
16 ; CHECK-NOT: convergent
17 ; CHECK-NEXT: define i32 @leaf()
18 define i32 @leaf() convergent {
22 ; CHECK: Function Attrs
23 ; CHECK-SAME: convergent
24 ; CHECK-NEXT: declare i32 @k()
25 declare i32 @k() convergent
27 ; CHECK: Function Attrs
28 ; CHECK-SAME: convergent
29 ; CHECK-NEXT: define i32 @extern()
30 define i32 @extern() convergent {
31 %a = call i32 @k() convergent
35 ; Convergent should not be removed on the function here. Although the call is
36 ; not explicitly convergent, it picks up the convergent attr from the callee.
38 ; CHECK: Function Attrs
39 ; CHECK-SAME: convergent
40 ; CHECK-NEXT: define i32 @extern_non_convergent_call()
41 define i32 @extern_non_convergent_call() convergent {
46 ; CHECK: Function Attrs
47 ; CHECK-SAME: convergent
48 ; CHECK-NEXT: define i32 @indirect_convergent_call(
49 define i32 @indirect_convergent_call(i32 ()* %f) convergent {
50 %a = call i32 %f() convergent
53 ; Give indirect_non_convergent_call the norecurse attribute so we get a
54 ; "Function Attrs" comment in the output.
56 ; CHECK: Function Attrs
57 ; CHECK-INDIRECT-NOT: convergent
58 ; CHECK-INDIRECT-NEXT: define i32 @indirect_non_convergent_call(
59 define i32 @indirect_non_convergent_call(i32 ()* %f) convergent norecurse {
64 ; CHECK: Function Attrs
65 ; CHECK-SAME: convergent
66 ; CHECK-NEXT: declare void @llvm.nvvm.barrier0()
67 declare void @llvm.nvvm.barrier0() convergent
69 ; CHECK: Function Attrs
70 ; CHECK-SAME: convergent
71 ; CHECK-NEXT: define i32 @intrinsic()
72 define i32 @intrinsic() convergent {
73 ; Implicitly convergent, because the intrinsic is convergent.
74 call void @llvm.nvvm.barrier0()
78 ; CHECK: Function Attrs
79 ; CHECK-NOT: convergent
80 ; CHECK-NEXT: define i32 @recursive1()
81 define i32 @recursive1() convergent {
82 %a = call i32 @recursive2() convergent
86 ; CHECK: Function Attrs
87 ; CHECK-NOT: convergent
88 ; CHECK-NEXT: define i32 @recursive2()
89 define i32 @recursive2() convergent {
90 %a = call i32 @recursive1() convergent
94 ; CHECK: Function Attrs
95 ; CHECK-SAME: convergent
96 ; CHECK-NEXT: define i32 @noopt()
97 define i32 @noopt() convergent optnone noinline {
98 %a = call i32 @noopt_friend() convergent
102 ; A function which is mutually-recursive with a convergent, optnone function
103 ; shouldn't have its convergent attribute stripped.
104 ; CHECK: Function Attrs
105 ; CHECK-SAME: convergent
106 ; CHECK-NEXT: define i32 @noopt_friend()
107 define i32 @noopt_friend() convergent {
108 %a = call i32 @noopt()