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
33define i64 addrspace(1)* @test_two_invokes(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1) gc "statepoint-example" personality i32 ()* @personality_function {
34; CHECK-LABEL: entry:
35entry:
36  ; CHECK: invoke
37  ; CHECK: statepoint
38  ; CHECK: some_call
39  %ret_val1 = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
40               to label %second_invoke unwind label %exceptional_return
41
42; CHECK-LABEL: second_invoke:
43second_invoke:
44  ; CHECK: invoke
45  ; CHECK: statepoint
46  ; CHECK: some_call
47  %ret_val2 = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %ret_val1)
48                to label %normal_return unwind label %exceptional_return
49
50; CHECK-LABEL: normal_return:
51normal_return:
52  ; CHECK: gc.result
53  ; CHECK: ret i64
54  ret i64 addrspace(1)* %ret_val2
55
56; CHECK: exceptional_return:
57; CHECK: ret i64
58
59exceptional_return:
60  %landing_pad4 = landingpad token
61          cleanup
62  ret i64 addrspace(1)* %obj1
63}
64
65define i64 addrspace(1)* @test_phi_node(i1 %cond, i64 addrspace(1)* %obj) gc "statepoint-example" personality i32 ()* @personality_function {
66; CHECK-LABEL: @test_phi_node
67; CHECK-LABEL: entry:
68entry:
69  br i1 %cond, label %left, label %right
70
71left:
72  %ret_val_left = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
73                    to label %merge unwind label %exceptional_return
74
75right:
76  %ret_val_right = invoke i64 addrspace(1)* @some_call(i64 addrspace(1)* %obj)
77                     to label %merge unwind label %exceptional_return
78
79; CHECK: merge[[A:[0-9]]]:
80; CHECK: gc.result
81; CHECK: br label %[[with_phi:merge[0-9]*]]
82
83; CHECK: merge[[B:[0-9]]]:
84; CHECK: gc.result
85; CHECK: br label %[[with_phi]]
86
87; CHECK: [[with_phi]]:
88; CHECK: phi
89; CHECK: ret i64 addrspace(1)* %ret_val
90merge:
91  %ret_val = phi i64 addrspace(1)* [%ret_val_left, %left], [%ret_val_right, %right]
92  ret i64 addrspace(1)* %ret_val
93
94; CHECK-LABEL: exceptional_return:
95; CHECK: ret i64 addrspace(1)*
96
97exceptional_return:
98  %landing_pad4 = landingpad token
99          cleanup
100  ret i64 addrspace(1)* %obj
101}
102
103declare void @do_safepoint()
104define void @gc.safepoint_poll() {
105; CHECK-LABEL: gc.safepoint_poll
106; CHECK-LABEL: entry
107; CHECK-NEXT: do_safepoint
108; CHECK-NEXT: ret void
109entry:
110  call void @do_safepoint()
111  ret void
112}
113