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