blob: 46370d7bf30344fdfaf7ddd11829ede11a9cab87 [file] [log] [blame]
Justin Lebar260854b2016-02-09 23:03:22 +00001; RUN: opt < %s -basicaa -functionattrs -rpo-functionattrs -S | FileCheck %s
2
3; CHECK: Function Attrs
4; CHECK-NOT: convergent
5; CHECK-NEXT: define i32 @nonleaf()
6define i32 @nonleaf() convergent {
7 %a = call i32 @leaf()
8 ret i32 %a
9}
10
11; CHECK: Function Attrs
12; CHECK-NOT: convergent
13; CHECK-NEXT: define i32 @leaf()
14define i32 @leaf() convergent {
15 ret i32 0
16}
17
18; CHECK: Function Attrs
19; CHECK-SAME: convergent
20; CHECK-NEXT: declare i32 @k()
21declare i32 @k() convergent
22
23; CHECK: Function Attrs
24; CHECK-SAME: convergent
25; CHECK-NEXT: define i32 @extern()
26define i32 @extern() convergent {
27 %a = call i32 @k()
28 ret i32 %a
29}
30
31; CHECK: Function Attrs
32; CHECK-SAME: convergent
33; CHECK-NEXT: define i32 @call_extern()
34define i32 @call_extern() convergent {
35 %a = call i32 @extern()
36 ret i32 %a
37}
38
39; CHECK: Function Attrs
40; CHECK-SAME: convergent
41; CHECK-NEXT: declare void @llvm.cuda.syncthreads()
42declare void @llvm.cuda.syncthreads() convergent
43
44; CHECK: Function Attrs
45; CHECK-SAME: convergent
46; CHECK-NEXT: define i32 @intrinsic()
47define i32 @intrinsic() convergent {
48 call void @llvm.cuda.syncthreads()
49 ret i32 0
50}
51
52@xyz = global i32 ()* null
53; CHECK: Function Attrs
54; CHECK-SAME: convergent
55; CHECK-NEXT: define i32 @functionptr()
56define i32 @functionptr() convergent {
57 %1 = load i32 ()*, i32 ()** @xyz
58 %2 = call i32 %1()
59 ret i32 %2
60}
61
62; CHECK: Function Attrs
63; CHECK-NOT: convergent
64; CHECK-NEXT: define i32 @recursive1()
65define i32 @recursive1() convergent {
66 %a = call i32 @recursive2()
67 ret i32 %a
68}
69
70; CHECK: Function Attrs
71; CHECK-NOT: convergent
72; CHECK-NEXT: define i32 @recursive2()
73define i32 @recursive2() convergent {
74 %a = call i32 @recursive1()
75 ret i32 %a
76}
77
78; CHECK: Function Attrs
79; CHECK-SAME: convergent
80; CHECK-NEXT: define i32 @noopt()
81define i32 @noopt() convergent optnone noinline {
82 %a = call i32 @noopt_friend()
83 ret i32 0
84}
85
86; A function which is mutually-recursive with a convergent, optnone function
87; shouldn't have its convergent attribute stripped.
88; CHECK: Function Attrs
89; CHECK-SAME: convergent
90; CHECK-NEXT: define i32 @noopt_friend()
91define i32 @noopt_friend() convergent {
92 %a = call i32 @noopt()
93 ret i32 0
94}