[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / RewriteStatepointsForGC / rematerialize-derived-pointers.ll
blob3f36b99404fcefdea714a73216571d0f2cd102fe
1 ; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
2 ; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
5 declare void @use_obj16(i16 addrspace(1)*) "gc-leaf-function"
6 declare void @use_obj32(i32 addrspace(1)*) "gc-leaf-function"
7 declare void @use_obj64(i64 addrspace(1)*) "gc-leaf-function"
9 declare void @do_safepoint()
11 define void @test_gep_const(i32 addrspace(1)* %base) gc "statepoint-example" {
12 ; CHECK-LABEL: test_gep_const
13 entry:
14   %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15
15 ; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15
16   call void @do_safepoint() [ "deopt"() ]
17 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7)
18 ; CHECK: bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
19 ; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 15
20   call void @use_obj32(i32 addrspace(1)* %base)
21   call void @use_obj32(i32 addrspace(1)* %ptr)
22   ret void
25 define void @test_gep_idx(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" {
26 ; CHECK-LABEL: test_gep_idx
27 entry:
28   %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 %idx
29 ; CHECK: getelementptr
30   call void @do_safepoint() [ "deopt"() ]
31 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7)
32 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
33 ; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 %idx
34   call void @use_obj32(i32 addrspace(1)* %base)
35   call void @use_obj32(i32 addrspace(1)* %ptr)
36   ret void
39 define void @test_bitcast(i32 addrspace(1)* %base) gc "statepoint-example" {
40 ; CHECK-LABEL: test_bitcast
41 entry:
42   %ptr = bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
43 ; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
44   call void @do_safepoint() [ "deopt"() ]
45 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7)
46 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
47 ; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)*
48   call void @use_obj32(i32 addrspace(1)* %base)
49   call void @use_obj64(i64 addrspace(1)* %ptr)
50   ret void
53 define void @test_bitcast_bitcast(i32 addrspace(1)* %base) gc "statepoint-example" {
54 ; CHECK-LABEL: test_bitcast_bitcast
55 entry:
56   %ptr1 = bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
57   %ptr2 = bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)*
58 ; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)*
59 ; CHECK: bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)*
60   call void @do_safepoint() [ "deopt"() ]
62 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7)
63 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
64 ; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)*
65 ; CHECK: bitcast i64 addrspace(1)* %ptr1.remat to i16 addrspace(1)*
66   call void @use_obj32(i32 addrspace(1)* %base)
67   call void @use_obj16(i16 addrspace(1)* %ptr2)
68   ret void
71 define void @test_addrspacecast_addrspacecast(i32 addrspace(1)* %base) gc "statepoint-example" {
72 ; CHECK-LABEL: test_addrspacecast_addrspacecast
73 entry:
74   %ptr1 = addrspacecast i32 addrspace(1)* %base to i32*
75   %ptr2 = addrspacecast i32* %ptr1 to i32 addrspace(1)*
76 ; CHECK: addrspacecast i32 addrspace(1)* %base to i32*
77 ; CHECK: addrspacecast i32* %ptr1 to i32 addrspace(1)*
78   call void @do_safepoint() [ "deopt"() ]
80 ; CHECK: %ptr2.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 7)
81 ; CHECK: %ptr2.relocated.casted = bitcast i8 addrspace(1)* %ptr2.relocated to i32 addrspace(1)*
82 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 8)
83 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)*
84   call void @use_obj32(i32 addrspace(1)* %base)
85   call void @use_obj32(i32 addrspace(1)* %ptr2)
86   ret void
89 define void @test_bitcast_gep(i32 addrspace(1)* %base) gc "statepoint-example" {
90 ; CHECK-LABEL: test_bitcast_gep
91 entry:
92   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
93 ; CHECK: getelementptr
94 ; CHECK: bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
95   %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
96   call void @do_safepoint() [ "deopt"() ]
98 ; CHECK: gc.relocate
99 ; CHECK: bitcast
100 ; CHECK: getelementptr
101 ; CHECK: bitcast
102   call void @use_obj32(i32 addrspace(1)* %base)
103   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
104   ret void
107 define void @test_intersecting_chains(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" {
108 ; CHECK-LABEL: test_intersecting_chains
109 entry:
110   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
111 ; CHECK: getelementptr
112   %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
113 ; CHECK: bitcast
114   %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
115 ; CHECK: bitcast
116   call void @do_safepoint() [ "deopt"() ]
118 ; CHECK: getelementptr
119 ; CHECK: bitcast
120 ; CHECK: getelementptr
121 ; CHECK: bitcast
122   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
123   call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
124   ret void
127 define void @test_cost_threshold(i32 addrspace(1)* %base, i32 %idx1, i32 %idx2, i32 %idx3) gc "statepoint-example" {
128 ; CHECK-LABEL: test_cost_threshold
129 entry:
130   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
131 ; CHECK: getelementptr
132   %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 %idx1
133 ; CHECK: getelementptr
134   %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 %idx2
135 ; CHECK: getelementptr
136   %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 %idx3
137 ; CHECK: getelementptr
138   %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep4 to i64 addrspace(1)*
139   call void @do_safepoint() [ "deopt"() ]
141 ; CHECK: gc.relocate
142 ; CHECK: bitcast
143 ; CHECK: gc.relocate
144 ; CHECK: bitcast
145   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
146   ret void
149 define void @test_two_derived(i32 addrspace(1)* %base) gc "statepoint-example" {
150 ; CHECK-LABEL: test_two_derived
151 entry:
152   %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15
153   %ptr2 = getelementptr i32, i32 addrspace(1)* %base, i32 12
154 ; CHECK: getelementptr
155 ; CHECK: getelementptr
156   call void @do_safepoint() [ "deopt"() ]
158 ; CHECK: gc.relocate
159 ; CHECK: bitcast
160 ; CHECK: getelementptr
161 ; CHECK: getelementptr
162   call void @use_obj32(i32 addrspace(1)* %ptr)
163   call void @use_obj32(i32 addrspace(1)* %ptr2)
164   ret void
167 define void @test_gep_smallint_array([3 x i32] addrspace(1)* %base) gc "statepoint-example" {
168 ; CHECK-LABEL: test_gep_smallint_array
169 entry:
170   %ptr = getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 2
171 ; CHECK: getelementptr
172   call void @do_safepoint() [ "deopt"() ]
174 ; CHECK: gc.relocate
175 ; CHECK: bitcast
176 ; CHECK: getelementptr
177   call void @use_obj32(i32 addrspace(1)* %ptr)
178   ret void
181 declare i32 @fake_personality_function()
183 define void @test_invoke(i32 addrspace(1)* %base) gc "statepoint-example" personality i32 ()* @fake_personality_function {
184 ; CHECK-LABEL: test_invoke
185 entry:
186   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
187 ; CHECK: getelementptr
188   %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
189 ; CHECK: bitcast
190   %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
191 ; CHECK: bitcast
192   invoke void @do_safepoint() [ "deopt"() ]
193           to label %normal unwind label %exception
195 normal:
196 ; CHECK: normal:
197 ; CHECK: gc.relocate
198 ; CHECK: bitcast
199 ; CHECK: getelementptr
200 ; CHECK: bitcast
201 ; CHECK: getelementptr
202 ; CHECK: bitcast
203   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
204   call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
205   ret void
207 exception:
208 ; CHECK: exception:
209   %landing_pad4 = landingpad token
210           cleanup
211 ; CHECK: gc.relocate
212 ; CHECK: bitcast
213 ; CHECK: getelementptr
214 ; CHECK: bitcast
215 ; CHECK: getelementptr
216 ; CHECK: bitcast
217   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
218   call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
219   ret void
222 define void @test_loop(i32 addrspace(1)* %base) gc "statepoint-example" {
223 ; CHECK-LABEL: test_loop
224 entry:
225   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
226 ; CHECK: getelementptr
227   br label %loop
229 loop:                                             ; preds = %loop, %entry
230 ; CHECK: phi i32 addrspace(1)* [ %ptr.gep, %entry ], [ %ptr.gep.remat, %loop ]
231 ; CHECK: phi i32 addrspace(1)* [ %base, %entry ], [ %base.relocated.casted, %loop ]
232   call void @use_obj32(i32 addrspace(1)* %ptr.gep)
233   call void @do_safepoint() [ "deopt"() ]
234 ; CHECK: gc.relocate
235 ; CHECK: bitcast
236 ; CHECK: getelementptr
237   br label %loop
240 define void @test_too_long(i32 addrspace(1)* %base) gc "statepoint-example" {
241 ; CHECK-LABEL: test_too_long
242 entry:
243   %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15
244   %ptr.gep1 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 15
245   %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep1, i32 15
246   %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 15
247   %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 15
248   %ptr.gep5 = getelementptr i32, i32 addrspace(1)* %ptr.gep4, i32 15
249   %ptr.gep6 = getelementptr i32, i32 addrspace(1)* %ptr.gep5, i32 15
250   %ptr.gep7 = getelementptr i32, i32 addrspace(1)* %ptr.gep6, i32 15
251   %ptr.gep8 = getelementptr i32, i32 addrspace(1)* %ptr.gep7, i32 15
252   %ptr.gep9 = getelementptr i32, i32 addrspace(1)* %ptr.gep8, i32 15
253   %ptr.gep10 = getelementptr i32, i32 addrspace(1)* %ptr.gep9, i32 15
254   %ptr.gep11 = getelementptr i32, i32 addrspace(1)* %ptr.gep10, i32 15
255   call void @do_safepoint() [ "deopt"() ]
256 ; CHECK: gc.relocate
257 ; CHECK: bitcast
258 ; CHECK: gc.relocate
259 ; CHECK: bitcast
260   call void @use_obj32(i32 addrspace(1)* %ptr.gep11)
261   ret void
265 declare i32 addrspace(1)* @new_instance() nounwind "gc-leaf-function"
267 ; remat the gep in presence of base pointer which is a phi node.
268 ; FIXME: We should remove the extra basephi.base as well.
269 define void @contains_basephi(i1 %cond) gc "statepoint-example" {
270 ; CHECK-LABEL: contains_basephi
271 entry:
272   %base1 = call i32 addrspace(1)* @new_instance()
273   %base2 = call i32 addrspace(1)* @new_instance()
274   br i1 %cond, label %here, label %there
276 here:
277   br label %merge
279 there:
280   br label %merge
282 merge:
283   ; CHECK: %basephi.base = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ], !is_base_value !0
284   ; CHECK: %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ]
285   ; CHECK: %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
286   ; CHECK: %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint
287   ; CHECK: %basephi.base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) ; (%basephi.base, %basephi.base)
288   ; CHECK: %basephi.base.relocated.casted = bitcast i8 addrspace(1)* %basephi.base.relocated to i32 addrspace(1)*
289   ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15
290   ; CHECK: call void @use_obj32(i32 addrspace(1)* %ptr.gep.remat)
294   %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ]
295   %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
296   call void @do_safepoint() ["deopt"() ]
297   call void @use_obj32(i32 addrspace(1)* %ptr.gep)
298   ret void
302 define void @test_intersecting_chains_with_phi(i1 %cond) gc "statepoint-example" {
303 ; CHECK-LABEL: test_intersecting_chains_with_phi
304 entry:
305   %base1 = call i32 addrspace(1)* @new_instance()
306   %base2 = call i32 addrspace(1)* @new_instance()
307   br i1 %cond, label %here, label %there
309 here:
310   br label %merge
312 there:
313   br label %merge
315 merge:
316   %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ]
317   %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
318   %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
319   %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
320   call void @do_safepoint() [ "deopt"() ]
321   ; CHECK: statepoint
322   ; CHECK: %ptr.gep.remat1 = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15
323   ; CHECK: %ptr.cast.remat = bitcast i32 addrspace(1)* %ptr.gep.remat1 to i64 addrspace(1)*
324   ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15
325   ; CHECK: %ptr.cast2.remat = bitcast i32 addrspace(1)* %ptr.gep.remat to i16 addrspace(1)*
326   ; CHECK: call void @use_obj64(i64 addrspace(1)* %ptr.cast.remat)
327   ; CHECK: call void @use_obj16(i16 addrspace(1)* %ptr.cast2.remat)
328   call void @use_obj64(i64 addrspace(1)* %ptr.cast)
329   call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
330   ret void