1; RUN: opt < %s -S -rewrite-statepoints-for-gc | FileCheck %s
2; RUN: opt < %s -S -passes=rewrite-statepoints-for-gc | FileCheck %s
3
4declare i64 addrspace(1)* @some_call(i64 addrspace(1)*)
5declare i32 @personality_function()
6
7define i64 addrspace(1)* @test_basic(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality_function {
8; CHECK-LABEL: entry:
9entry:
10  ; CHECK: invoke
11  ; CHECK: statepoint
12  ; CHECK: some_call
13  %ret_val = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
14               to label %normal_return unwind label %exceptional_return
15
16; CHECK-LABEL: normal_return:
17; CHECK: gc.result
18; CHECK: ret i64
19
20normal_return:
21  ret i64 addrspace(1)* %ret_val
22
23; CHECK-LABEL: exceptional_return:
24; CHECK: landingpad
25; CHECK: ret i64
26
27exceptional_return:
28  %landing_pad4 = landingpad token
29          cleanup
30  ret i64 addrspace(1)* %obj1
31}
32
33declare <4 x i64 addrspace(1)*> @some_vector_call(<4 x i64 addrspace(1)*>)
34
35define <4 x i64 addrspace(1)*> @test_basic_vector(<4 x i64 addrspace(1)*> %objs, <4 x i64 addrspace(1)*> %objs1) gc "statepoint-example" personality i32 ()* @personality_function {
36; CHECK-LABEL: @test_basic_vector
37entry:
38; CHECK: invoke{{.*}}llvm.experimental.gc.statepoint{{.*}}some_vector_call
39  %ret_val = invoke <4 x i64 addrspace(1)*> @some_vector_call(<4 x i64 addrspace(1)*> %objs)
40               to label %normal_return unwind label %exceptional_return
41
42; CHECK-LABEL: normal_return:
43; CHECK: gc.result
44; CHECK: ret <4 x i64 addrspace(1)*>
45
46normal_return:
47  ret <4 x i64 addrspace(1)*> %ret_val
48
49; CHECK-LABEL: exceptional_return:
50; CHECK: landingpad
51; CHECK: ret <4 x i64 addrspace(1)*>
52
53exceptional_return:
54  %landing_pad4 = landingpad token
55          cleanup
56  ret <4 x i64 addrspace(1)*> %objs1
57}
58
59define i64 addrspace(1)* @test_two_invokes(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality_function {
60; CHECK-LABEL: entry:
61entry:
62  ; CHECK: invoke
63  ; CHECK: statepoint
64  ; CHECK: some_call
65  %ret_val1 = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
66               to label %second_invoke unwind label %exceptional_return
67
68; CHECK-LABEL: second_invoke:
69second_invoke:
70  ; CHECK: invoke
71  ; CHECK: statepoint
72  ; CHECK: some_call
73  %ret_val2 = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %ret_val1)
74                to label %normal_return unwind label %exceptional_return
75
76; CHECK-LABEL: normal_return:
77normal_return:
78  ; CHECK: gc.result
79  ; CHECK: ret i64
80  ret i64 addrspace(1)* %ret_val2
81
82; CHECK: exceptional_return:
83; CHECK: ret i64
84
85exceptional_return:
86  %landing_pad4 = landingpad token
87          cleanup
88  ret i64 addrspace(1)* %obj1
89}
90
91define i64 addrspace(1)* @test_phi_node(i1 %cond, i64 addrspace(1)* %obj) gc "statepoint-example" personality i32 ()* @personality_function {
92; CHECK-LABEL: @test_phi_node
93; CHECK-LABEL: entry:
94entry:
95  br i1 %cond, label %left, label %right
96
97left:
98  %ret_val_left = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
99                    to label %merge unwind label %exceptional_return
100
101right:
102  %ret_val_right = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
103                     to label %merge unwind label %exceptional_return
104
105; CHECK: merge[[A:[0-9]]]:
106; CHECK: gc.result
107; CHECK: br label %[[with_phi:merge[0-9]*]]
108
109; CHECK: merge[[B:[0-9]]]:
110; CHECK: gc.result
111; CHECK: br label %[[with_phi]]
112
113; CHECK: [[with_phi]]:
114; CHECK: phi
115; CHECK: ret i64 addrspace(1)* %ret_val
116merge:
117  %ret_val = phi i64 addrspace(1)* [%ret_val_left, %left], [%ret_val_right, %right]
118  ret i64 addrspace(1)* %ret_val
119
120; CHECK-LABEL: exceptional_return:
121; CHECK: ret i64 addrspace(1)*
122
123exceptional_return:
124  %landing_pad4 = landingpad token
125          cleanup
126  ret i64 addrspace(1)* %obj
127}
128
129declare void @do_safepoint()
130define void @gc.safepoint_poll() {
131; CHECK-LABEL: gc.safepoint_poll
132; CHECK-LABEL: entry
133; CHECK-NEXT: do_safepoint
134; CHECK-NEXT: ret void
135entry:
136  call void @do_safepoint()
137  ret void
138}
139