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 token (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(token %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 token (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(token %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 token (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(token %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_bitcast"(i32 addrspace(1)* %base) gc "statepoint-example" {
51; CHECK-LABEL: test_bitcast_bitcast
52entry:
53  %ptr1 = bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
54  %ptr2 = bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)*
55  ; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
56  ; CHECK: bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)*
57  %sp = call token (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: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %sp, i32 7, i32 7)
59  ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
60  ; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)*
61  ; CHECK: bitcast i64 addrspace(1)* %ptr1.remat to i16 addrspace(1)*
62  call void @use_obj32(i32 addrspace(1)* %base)
63  call void @use_obj16(i16 addrspace(1)* %ptr2)
64  ret void
65}
66
67define void @"test_addrspacecast_addrspacecast"(i32 addrspace(1)* %base) gc "statepoint-example" {
68; CHECK-LABEL: test_addrspacecast_addrspacecast
69entry:
70  %ptr1 = addrspacecast i32 addrspace(1)* %base to i32*
71  %ptr2 = addrspacecast i32* %ptr1 to i32 addrspace(1)*
72  ; CHECK: addrspacecast i32 addrspace(1)* %base to i32*
73  ; CHECK: addrspacecast i32* %ptr1 to i32 addrspace(1)*
74  %sp = call token (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)
75  ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %sp, i32 7, i32 7)
76  ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
77  ; CHECK: %ptr2.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %sp, i32 7, i32 8)
78  ; CHECK: %ptr2.relocated.casted = bitcast i8 addrspace(1)* %ptr2.relocated to i32 addrspace(1)*
79  call void @use_obj32(i32 addrspace(1)* %base)
80  call void @use_obj32(i32 addrspace(1)* %ptr2)
81  ret void
82}
83
84define void @"test_bitcast_gep"(i32 addrspace(1)* %base) gc "statepoint-example" {
85; CHECK-LABEL: test_bitcast_gep
86entry:
87  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
88  ; CHECK: getelementptr
89  %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
90  ; CHECK: bitcast
91  %sp = call token (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)
92  ; CHECK: gc.relocate
93  ; CHECK: bitcast
94  ; CHECK: getelementptr
95  ; CHECK: bitcast
96  call void @use_obj32(i32 addrspace(1)* %base)
97  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
98  ret void
99}
100
101define void @"test_intersecting_chains"(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" {
102; CHECK-LABEL: test_intersecting_chains
103entry:
104  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
105  ; CHECK: getelementptr
106  %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
107  ; CHECK: bitcast
108  %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
109  ; CHECK: bitcast
110  %sp = call token (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)
111  ; CHECK: getelementptr
112  ; CHECK: bitcast
113  ; CHECK: getelementptr
114  ; CHECK: bitcast
115  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
116  call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
117  ret void
118}
119
120define void @"test_cost_threshold"(i32 addrspace(1)* %base, i32 %idx1, i32 %idx2, i32 %idx3) gc "statepoint-example" {
121; CHECK-LABEL: test_cost_threshold
122entry:
123  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
124  ; CHECK: getelementptr
125  %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 %idx1
126  ; CHECK: getelementptr
127  %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 %idx2
128  ; CHECK: getelementptr
129  %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 %idx3
130  ; CHECK: getelementptr
131  %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep4 to i64 addrspace(1)*
132  ; CHECK: bitcast
133  %sp = call token (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)
134  ; CHECK: gc.relocate
135  ; CHECK: bitcast
136  ; CHECK: gc.relocate
137  ; CHECK: bitcast
138  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
139  ret void
140}
141
142define void @"test_two_derived"(i32 addrspace(1)* %base) gc "statepoint-example" {
143; CHECK-LABEL: test_two_derived
144entry:
145  %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15
146  %ptr2 = getelementptr i32, i32 addrspace(1)* %base, i32 12
147  ; CHECK: getelementptr
148  ; CHECK: getelementptr
149  %sp = call token (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  ; CHECK: gc.relocate
151  ; CHECK: bitcast
152  ; CHECK: getelementptr
153  ; CHECK: getelementptr
154  call void @use_obj32(i32 addrspace(1)* %ptr)
155  call void @use_obj32(i32 addrspace(1)* %ptr2)
156  ret void
157}
158
159define void @"test_gep_smallint_array"([3 x i32] addrspace(1)* %base) gc "statepoint-example" {
160; CHECK-LABEL: test_gep_smallint_array
161entry:
162  %ptr = getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 2
163  ; CHECK: getelementptr
164  %sp = call token (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)
165  ; CHECK: gc.relocate
166  ; CHECK: bitcast
167  ; CHECK: getelementptr
168  call void @use_obj32(i32 addrspace(1)* %ptr)
169  ret void
170}
171
172declare i32 @fake_personality_function()
173
174define void @"test_invoke"(i32 addrspace(1)* %base) gc "statepoint-example" personality i32 ()* @fake_personality_function {
175; CHECK-LABEL: test_invoke
176entry:
177  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
178  ; CHECK: getelementptr
179  %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
180  ; CHECK: bitcast
181  %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
182  ; CHECK: bitcast
183  %sp = invoke token (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)
184                to label %normal unwind label %exception
185
186normal:
187  ; CHECK-LABEL: normal:
188  ; CHECK: gc.relocate
189  ; CHECK: bitcast
190  ; CHECK: getelementptr
191  ; CHECK: bitcast
192  ; CHECK: getelementptr
193  ; CHECK: bitcast
194  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
195  call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
196  ret void
197
198exception:
199  ; CHECK-LABEL: exception:
200  %landing_pad4 = landingpad token
201          cleanup
202  ; CHECK: gc.relocate
203  ; CHECK: bitcast
204  ; CHECK: getelementptr
205  ; CHECK: bitcast
206  ; CHECK: getelementptr
207  ; CHECK: bitcast
208  call void @use_obj64(i64 addrspace(1)* %ptr.cast)
209  call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
210  ret void
211}
212
213define void @"test_loop"(i32 addrspace(1)* %base) gc "statepoint-example" {
214; CHECK-LABEL: test_loop
215entry:
216  %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
217  ; CHECK: getelementptr
218  br label %loop
219
220loop:
221  ; CHECK: phi i32 addrspace(1)* [ %ptr.gep, %entry ], [ %ptr.gep.remat, %loop ]
222  ; CHECK: phi i32 addrspace(1)* [ %base, %entry ], [ %base.relocated.casted, %loop ]
223  call void @use_obj32(i32 addrspace(1)* %ptr.gep)
224  %sp = call token (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)
225  ; CHECK: gc.relocate
226  ; CHECK: bitcast
227  ; CHECK: getelementptr
228  br label %loop
229}
230
231define void @"test_too_long"(i32 addrspace(1)* %base) gc "statepoint-example" {
232; CHECK-LABEL: test_too_long
233entry:
234  %ptr.gep   = getelementptr i32, i32 addrspace(1)* %base, i32 15
235  %ptr.gep1  = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 15
236  %ptr.gep2  = getelementptr i32, i32 addrspace(1)* %ptr.gep1, i32 15
237  %ptr.gep3  = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 15
238  %ptr.gep4  = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 15
239  %ptr.gep5  = getelementptr i32, i32 addrspace(1)* %ptr.gep4, i32 15
240  %ptr.gep6  = getelementptr i32, i32 addrspace(1)* %ptr.gep5, i32 15
241  %ptr.gep7  = getelementptr i32, i32 addrspace(1)* %ptr.gep6, i32 15
242  %ptr.gep8  = getelementptr i32, i32 addrspace(1)* %ptr.gep7, i32 15
243  %ptr.gep9  = getelementptr i32, i32 addrspace(1)* %ptr.gep8, i32 15
244  %ptr.gep10 = getelementptr i32, i32 addrspace(1)* %ptr.gep9, i32 15
245  %ptr.gep11 = getelementptr i32, i32 addrspace(1)* %ptr.gep10, i32 15
246  %sp = call token (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)
247  ; CHECK: gc.relocate
248  ; CHECK: bitcast
249  ; CHECK: gc.relocate
250  ; CHECK: bitcast
251  call void @use_obj32(i32 addrspace(1)* %ptr.gep11)
252  ret void
253}
254
255
256declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
257