1; RUN: opt %s -rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s
2
3declare void @use_obj16(i16 addrspace(1)*)
4declare void @use_obj32(i32 addrspace(1)*)
5declare void @use_obj64(i64 addrspace(1)*)
6declare void @do_safepoint()
7
8define void @"test_gep_const"(i32 addrspace(1)* %base) gc "statepoint-example" {
9; CHECK-LABEL: test_gep_const
10entry:
11  %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15
12  ; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15
13  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
14  ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %sp, i32 7, i32 7)
15  ; CHECK: bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
16  ; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 15
17  call void @use_obj32(i32 addrspace(1)* %base)
18  call void @use_obj32(i32 addrspace(1)* %ptr)
19  ret void
20}
21
22define void @"test_gep_idx"(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" {
23; CHECK-LABEL: test_gep_idx
24entry:
25  %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 %idx
26  ; CHECK: getelementptr
27  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
28  ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %sp, i32 7, i32 7)
29  ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
30  ; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 %idx
31  call void @use_obj32(i32 addrspace(1)* %base)
32  call void @use_obj32(i32 addrspace(1)* %ptr)
33  ret void
34}
35
36define void @"test_bitcast"(i32 addrspace(1)* %base) gc "statepoint-example" {
37; CHECK-LABEL: test_bitcast
38entry:
39  %ptr = bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
40  ; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
41  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
42  ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(i32 %sp, i32 7, i32 7)
43  ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
44  ; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)*
45  call void @use_obj32(i32 addrspace(1)* %base)
46  call void @use_obj64(i64 addrspace(1)* %ptr)
47  ret void
48}
49
50define void @"test_bitcast_gep"(i32 addrspace(1)* %base) gc "statepoint-example" {
51; CHECK-LABEL: test_bitcast_gep
52entry:
53  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
54  ; CHECK: getelementptr
55  %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
56  ; CHECK: bitcast
57  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
58  ; CHECK: gc.relocate
59  ; CHECK: bitcast
60  ; CHECK: getelementptr
61  ; CHECK: bitcast
62  call void @use_obj32(i32 addrspace(1)* %base)
63  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
64  ret void
65}
66
67define void @"test_intersecting_chains"(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" {
68; CHECK-LABEL: test_intersecting_chains
69entry:
70  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
71  ; CHECK: getelementptr
72  %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
73  ; CHECK: bitcast
74  %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
75  ; CHECK: bitcast
76  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
77  ; CHECK: getelementptr
78  ; CHECK: bitcast
79  ; CHECK: getelementptr
80  ; CHECK: bitcast
81  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
82  call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
83  ret void
84}
85
86define void @"test_cost_threshold"(i32 addrspace(1)* %base, i32 %idx1, i32 %idx2, i32 %idx3) gc "statepoint-example" {
87; CHECK-LABEL: test_cost_threshold
88entry:
89  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
90  ; CHECK: getelementptr
91  %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 %idx1
92  ; CHECK: getelementptr
93  %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 %idx2
94  ; CHECK: getelementptr
95  %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 %idx3
96  ; CHECK: getelementptr
97  %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep4 to i64 addrspace(1)*
98  ; CHECK: bitcast
99  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
100  ; CHECK: gc.relocate
101  ; CHECK: bitcast
102  ; CHECK: gc.relocate
103  ; CHECK: bitcast
104  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
105  ret void
106}
107
108define void @"test_two_derived"(i32 addrspace(1)* %base) gc "statepoint-example" {
109; CHECK-LABEL: test_two_derived
110entry:
111  %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15
112  %ptr2 = getelementptr i32, i32 addrspace(1)* %base, i32 12
113  ; CHECK: getelementptr
114  ; CHECK: getelementptr
115  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
116  ; CHECK: gc.relocate
117  ; CHECK: bitcast
118  ; CHECK: getelementptr
119  ; CHECK: getelementptr
120  call void @use_obj32(i32 addrspace(1)* %ptr)
121  call void @use_obj32(i32 addrspace(1)* %ptr2)
122  ret void
123}
124
125define void @"test_gep_smallint_array"([3 x i32] addrspace(1)* %base) gc "statepoint-example" {
126; CHECK-LABEL: test_gep_smallint_array
127entry:
128  %ptr = getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 2
129  ; CHECK: getelementptr
130  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
131  ; CHECK: gc.relocate
132  ; CHECK: bitcast
133  ; CHECK: getelementptr
134  call void @use_obj32(i32 addrspace(1)* %ptr)
135  ret void
136}
137
138declare i32 @fake_personality_function()
139
140define void @"test_invoke"(i32 addrspace(1)* %base) gc "statepoint-example" personality i32 ()* @fake_personality_function {
141; CHECK-LABEL: test_invoke
142entry:
143  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
144  ; CHECK: getelementptr
145  %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
146  ; CHECK: bitcast
147  %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
148  ; CHECK: bitcast
149  %sp = invoke i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
150                to label %normal unwind label %exception
151
152normal:
153  ; CHECK-LABEL: normal:
154  ; CHECK: gc.relocate
155  ; CHECK: bitcast
156  ; CHECK: getelementptr
157  ; CHECK: bitcast
158  ; CHECK: getelementptr
159  ; CHECK: bitcast
160  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
161  call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
162  ret void
163
164exception:
165  ; CHECK-LABEL: exception:
166  %landing_pad4 = landingpad { i8*, i32 }
167          cleanup
168  ; CHECK: gc.relocate
169  ; CHECK: bitcast
170  ; CHECK: getelementptr
171  ; CHECK: bitcast
172  ; CHECK: getelementptr
173  ; CHECK: bitcast
174  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
175  call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
176  ret void
177}
178
179define void @"test_loop"(i32 addrspace(1)* %base) gc "statepoint-example" {
180; CHECK-LABEL: test_loop
181entry:
182  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
183  ; CHECK: getelementptr
184  br label %loop
185
186loop:
187  ; CHECK: phi i32 addrspace(1)* [ %ptr.gep, %entry ], [ %ptr.gep.remat, %loop ]
188  ; CHECK: phi i32 addrspace(1)* [ %base, %entry ], [ %base.relocated.casted, %loop ]
189  call void @use_obj32(i32 addrspace(1)* %ptr.gep)
190  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
191  ; CHECK: gc.relocate
192  ; CHECK: bitcast
193  ; CHECK: getelementptr
194  br label %loop
195}
196
197define void @"test_too_long"(i32 addrspace(1)* %base) gc "statepoint-example" {
198; CHECK-LABEL: test_too_long
199entry:
200  %ptr.gep   = getelementptr i32, i32 addrspace(1)* %base, i32 15
201  %ptr.gep1  = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 15
202  %ptr.gep2  = getelementptr i32, i32 addrspace(1)* %ptr.gep1, i32 15
203  %ptr.gep3  = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 15
204  %ptr.gep4  = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 15
205  %ptr.gep5  = getelementptr i32, i32 addrspace(1)* %ptr.gep4, i32 15
206  %ptr.gep6  = getelementptr i32, i32 addrspace(1)* %ptr.gep5, i32 15
207  %ptr.gep7  = getelementptr i32, i32 addrspace(1)* %ptr.gep6, i32 15
208  %ptr.gep8  = getelementptr i32, i32 addrspace(1)* %ptr.gep7, i32 15
209  %ptr.gep9  = getelementptr i32, i32 addrspace(1)* %ptr.gep8, i32 15
210  %ptr.gep10 = getelementptr i32, i32 addrspace(1)* %ptr.gep9, i32 15
211  %ptr.gep11 = getelementptr i32, i32 addrspace(1)* %ptr.gep10, i32 15
212  %sp = call i32 (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0)
213  ; CHECK: gc.relocate
214  ; CHECK: bitcast
215  ; CHECK: gc.relocate
216  ; CHECK: bitcast
217  call void @use_obj32(i32 addrspace(1)* %ptr.gep11)
218  ret void
219}
220
221
222declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
223