1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -max-registers-for-gc-values=4 -fixup-allow-gcptr-in-csr=true < %s | FileCheck %s
4 target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-pc-linux-gnu"
7 declare i1 @return_i1()
9 declare void @consume(ptr addrspace(1))
10 declare i32 @consume1(i32) gc "statepoint-example"
11 declare void @consume2(ptr addrspace(1), ptr addrspace(1))
12 declare void @consume3(float) gc "statepoint-example"
13 declare float @consume4(i64) gc "statepoint-example"
14 declare void @consume5(ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1), ptr addrspace(1))
16 declare void @use1(ptr addrspace(1), ptr addrspace(1))
18 ; test most simple relocate
19 define i1 @test_relocate(ptr addrspace(1) %a) gc "statepoint-example" {
20 ; CHECK-LABEL: test_relocate:
21 ; CHECK: # %bb.0: # %entry
22 ; CHECK-NEXT: pushq %rbp
23 ; CHECK-NEXT: .cfi_def_cfa_offset 16
24 ; CHECK-NEXT: pushq %rbx
25 ; CHECK-NEXT: .cfi_def_cfa_offset 24
26 ; CHECK-NEXT: pushq %rax
27 ; CHECK-NEXT: .cfi_def_cfa_offset 32
28 ; CHECK-NEXT: .cfi_offset %rbx, -24
29 ; CHECK-NEXT: .cfi_offset %rbp, -16
30 ; CHECK-NEXT: movq %rdi, %rbx
31 ; CHECK-NEXT: callq return_i1@PLT
33 ; CHECK-NEXT: movl %eax, %ebp
34 ; CHECK-NEXT: movq %rbx, %rdi
35 ; CHECK-NEXT: callq consume@PLT
36 ; CHECK-NEXT: movl %ebp, %eax
37 ; CHECK-NEXT: addq $8, %rsp
38 ; CHECK-NEXT: .cfi_def_cfa_offset 24
39 ; CHECK-NEXT: popq %rbx
40 ; CHECK-NEXT: .cfi_def_cfa_offset 16
41 ; CHECK-NEXT: popq %rbp
42 ; CHECK-NEXT: .cfi_def_cfa_offset 8
45 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %a)]
46 %rel1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
47 %res1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
48 call void @consume(ptr addrspace(1) %rel1)
52 ; test pointer variables intermixed with pointer constants
53 define void @test_mixed(ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %c) gc "statepoint-example" {
54 ; CHECK-LABEL: test_mixed:
55 ; CHECK: # %bb.0: # %entry
56 ; CHECK-NEXT: pushq %r15
57 ; CHECK-NEXT: .cfi_def_cfa_offset 16
58 ; CHECK-NEXT: pushq %r14
59 ; CHECK-NEXT: .cfi_def_cfa_offset 24
60 ; CHECK-NEXT: pushq %rbx
61 ; CHECK-NEXT: .cfi_def_cfa_offset 32
62 ; CHECK-NEXT: .cfi_offset %rbx, -32
63 ; CHECK-NEXT: .cfi_offset %r14, -24
64 ; CHECK-NEXT: .cfi_offset %r15, -16
65 ; CHECK-NEXT: movq %rdx, %rbx
66 ; CHECK-NEXT: movq %rsi, %r14
67 ; CHECK-NEXT: movq %rdi, %r15
68 ; CHECK-NEXT: callq func@PLT
70 ; CHECK-NEXT: movq %r15, %rdi
71 ; CHECK-NEXT: xorl %esi, %esi
72 ; CHECK-NEXT: movq %r14, %rdx
73 ; CHECK-NEXT: xorl %ecx, %ecx
74 ; CHECK-NEXT: movq %rbx, %r8
75 ; CHECK-NEXT: callq consume5@PLT
76 ; CHECK-NEXT: popq %rbx
77 ; CHECK-NEXT: .cfi_def_cfa_offset 24
78 ; CHECK-NEXT: popq %r14
79 ; CHECK-NEXT: .cfi_def_cfa_offset 16
80 ; CHECK-NEXT: popq %r15
81 ; CHECK-NEXT: .cfi_def_cfa_offset 8
84 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %a, ptr addrspace(1) null, ptr addrspace(1) %b, ptr addrspace(1) null, ptr addrspace(1) %c)]
85 %rel1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
86 %rel2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 1, i32 1)
87 %rel3 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 2, i32 2)
88 %rel4 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 3, i32 3)
89 %rel5 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 4, i32 4)
90 call void @consume5(ptr addrspace(1) %rel1, ptr addrspace(1) %rel2, ptr addrspace(1) %rel3, ptr addrspace(1) %rel4, ptr addrspace(1) %rel5)
94 ; same as above, but for alloca
95 define ptr addrspace(1) @test_alloca(ptr addrspace(1) %ptr) gc "statepoint-example" {
96 ; CHECK-LABEL: test_alloca:
97 ; CHECK: # %bb.0: # %entry
98 ; CHECK-NEXT: pushq %r14
99 ; CHECK-NEXT: .cfi_def_cfa_offset 16
100 ; CHECK-NEXT: pushq %rbx
101 ; CHECK-NEXT: .cfi_def_cfa_offset 24
102 ; CHECK-NEXT: pushq %rax
103 ; CHECK-NEXT: .cfi_def_cfa_offset 32
104 ; CHECK-NEXT: .cfi_offset %rbx, -24
105 ; CHECK-NEXT: .cfi_offset %r14, -16
106 ; CHECK-NEXT: movq %rdi, %rbx
107 ; CHECK-NEXT: movq %rdi, (%rsp)
108 ; CHECK-NEXT: callq return_i1@PLT
109 ; CHECK-NEXT: .Ltmp2:
110 ; CHECK-NEXT: movq (%rsp), %r14
111 ; CHECK-NEXT: movq %rbx, %rdi
112 ; CHECK-NEXT: callq consume@PLT
113 ; CHECK-NEXT: movq %r14, %rax
114 ; CHECK-NEXT: addq $8, %rsp
115 ; CHECK-NEXT: .cfi_def_cfa_offset 24
116 ; CHECK-NEXT: popq %rbx
117 ; CHECK-NEXT: .cfi_def_cfa_offset 16
118 ; CHECK-NEXT: popq %r14
119 ; CHECK-NEXT: .cfi_def_cfa_offset 8
122 %alloca = alloca ptr addrspace(1), align 8
123 store ptr addrspace(1) %ptr, ptr %alloca
124 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr %alloca, ptr addrspace(1) %ptr)]
125 %rel1 = load ptr addrspace(1), ptr %alloca
126 %rel2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 1, i32 1)
127 call void @consume(ptr addrspace(1) %rel2)
128 ret ptr addrspace(1) %rel1
131 ; test base != derived
132 define void @test_base_derived(ptr addrspace(1) %base, ptr addrspace(1) %derived) gc "statepoint-example" {
133 ; CHECK-LABEL: test_base_derived:
135 ; CHECK-NEXT: pushq %r14
136 ; CHECK-NEXT: .cfi_def_cfa_offset 16
137 ; CHECK-NEXT: pushq %rbx
138 ; CHECK-NEXT: .cfi_def_cfa_offset 24
139 ; CHECK-NEXT: pushq %rax
140 ; CHECK-NEXT: .cfi_def_cfa_offset 32
141 ; CHECK-NEXT: .cfi_offset %rbx, -24
142 ; CHECK-NEXT: .cfi_offset %r14, -16
143 ; CHECK-NEXT: movq %rsi, %rbx
144 ; CHECK-NEXT: movq %rdi, %r14
145 ; CHECK-NEXT: callq func@PLT
146 ; CHECK-NEXT: .Ltmp3:
147 ; CHECK-NEXT: movq %rbx, %rdi
148 ; CHECK-NEXT: callq consume@PLT
149 ; CHECK-NEXT: addq $8, %rsp
150 ; CHECK-NEXT: .cfi_def_cfa_offset 24
151 ; CHECK-NEXT: popq %rbx
152 ; CHECK-NEXT: .cfi_def_cfa_offset 16
153 ; CHECK-NEXT: popq %r14
154 ; CHECK-NEXT: .cfi_def_cfa_offset 8
156 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %base, ptr addrspace(1) %derived)]
157 %reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 1)
158 call void @consume(ptr addrspace(1) %reloc)
162 ; deopt GC pointer not present in GC args goes on reg.
163 define void @test_deopt_gcpointer(ptr addrspace(1) %a, ptr addrspace(1) %b) gc "statepoint-example" {
164 ; CHECK-LABEL: test_deopt_gcpointer:
166 ; CHECK-NEXT: pushq %r14
167 ; CHECK-NEXT: .cfi_def_cfa_offset 16
168 ; CHECK-NEXT: pushq %rbx
169 ; CHECK-NEXT: .cfi_def_cfa_offset 24
170 ; CHECK-NEXT: pushq %rax
171 ; CHECK-NEXT: .cfi_def_cfa_offset 32
172 ; CHECK-NEXT: .cfi_offset %rbx, -24
173 ; CHECK-NEXT: .cfi_offset %r14, -16
174 ; CHECK-NEXT: movq %rsi, %rbx
175 ; CHECK-NEXT: movq %rdi, %r14
176 ; CHECK-NEXT: callq func@PLT
177 ; CHECK-NEXT: .Ltmp4:
178 ; CHECK-NEXT: movq %rbx, %rdi
179 ; CHECK-NEXT: callq consume@PLT
180 ; CHECK-NEXT: addq $8, %rsp
181 ; CHECK-NEXT: .cfi_def_cfa_offset 24
182 ; CHECK-NEXT: popq %rbx
183 ; CHECK-NEXT: .cfi_def_cfa_offset 16
184 ; CHECK-NEXT: popq %r14
185 ; CHECK-NEXT: .cfi_def_cfa_offset 8
187 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["deopt" (ptr addrspace(1) %a), "gc-live" (ptr addrspace(1) %b)]
188 %rel = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
189 call void @consume(ptr addrspace(1) %rel)
193 ;; Two gc.relocates of the same input, should require only a single spill/fill
194 define void @test_gcrelocate_uniqueing(ptr addrspace(1) %ptr) gc "statepoint-example" {
195 ; CHECK-LABEL: test_gcrelocate_uniqueing:
197 ; CHECK-NEXT: pushq %rbx
198 ; CHECK-NEXT: .cfi_def_cfa_offset 16
199 ; CHECK-NEXT: .cfi_offset %rbx, -16
200 ; CHECK-NEXT: movq %rdi, %rbx
201 ; CHECK-NEXT: callq func@PLT
202 ; CHECK-NEXT: .Ltmp5:
203 ; CHECK-NEXT: movq %rbx, %rdi
204 ; CHECK-NEXT: movq %rbx, %rsi
205 ; CHECK-NEXT: callq consume2@PLT
206 ; CHECK-NEXT: popq %rbx
207 ; CHECK-NEXT: .cfi_def_cfa_offset 8
209 %tok = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["deopt" (ptr addrspace(1) %ptr, i32 undef), "gc-live" (ptr addrspace(1) %ptr, ptr addrspace(1) %ptr)]
210 %a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0)
211 %b = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 1, i32 1)
212 call void @consume2(ptr addrspace(1) %a, ptr addrspace(1) %b)
216 ; Two gc.relocates of a bitcasted pointer should only require a single spill/fill
217 define void @test_gcptr_uniqueing(ptr addrspace(1) %ptr) gc "statepoint-example" {
218 ; CHECK-LABEL: test_gcptr_uniqueing:
220 ; CHECK-NEXT: pushq %rbx
221 ; CHECK-NEXT: .cfi_def_cfa_offset 16
222 ; CHECK-NEXT: .cfi_offset %rbx, -16
223 ; CHECK-NEXT: movq %rdi, %rbx
224 ; CHECK-NEXT: callq func@PLT
225 ; CHECK-NEXT: .Ltmp6:
226 ; CHECK-NEXT: movq %rbx, %rdi
227 ; CHECK-NEXT: movq %rbx, %rsi
228 ; CHECK-NEXT: callq use1@PLT
229 ; CHECK-NEXT: popq %rbx
230 ; CHECK-NEXT: .cfi_def_cfa_offset 8
232 %tok = tail call token (i64, i32, ptr, i32, i32, ...)
233 @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["deopt" (ptr addrspace(1) %ptr, i32 undef), "gc-live" (ptr addrspace(1) %ptr, ptr addrspace(1) %ptr)]
234 %a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 0, i32 0)
235 %b = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %tok, i32 1, i32 1)
236 call void @use1(ptr addrspace(1) %a, ptr addrspace(1) %b)
241 ; Cross-basicblock relocates are handled with spilling for now.
242 define i1 @test_cross_bb(ptr addrspace(1) %a, i1 %external_cond) gc "statepoint-example" {
243 ; CHECK-LABEL: test_cross_bb:
244 ; CHECK: # %bb.0: # %entry
245 ; CHECK-NEXT: pushq %rbp
246 ; CHECK-NEXT: .cfi_def_cfa_offset 16
247 ; CHECK-NEXT: pushq %rbx
248 ; CHECK-NEXT: .cfi_def_cfa_offset 24
249 ; CHECK-NEXT: pushq %rax
250 ; CHECK-NEXT: .cfi_def_cfa_offset 32
251 ; CHECK-NEXT: .cfi_offset %rbx, -24
252 ; CHECK-NEXT: .cfi_offset %rbp, -16
253 ; CHECK-NEXT: movl %esi, %ebp
254 ; CHECK-NEXT: movq %rdi, %rbx
255 ; CHECK-NEXT: callq return_i1@PLT
256 ; CHECK-NEXT: .Ltmp7:
257 ; CHECK-NEXT: testb $1, %bpl
258 ; CHECK-NEXT: je .LBB7_2
259 ; CHECK-NEXT: # %bb.1: # %left
260 ; CHECK-NEXT: movq %rbx, %rdi
261 ; CHECK-NEXT: movl %eax, %ebx
262 ; CHECK-NEXT: callq consume@PLT
263 ; CHECK-NEXT: movl %ebx, %eax
264 ; CHECK-NEXT: jmp .LBB7_3
265 ; CHECK-NEXT: .LBB7_2: # %right
266 ; CHECK-NEXT: movb $1, %al
267 ; CHECK-NEXT: .LBB7_3: # %right
268 ; CHECK-NEXT: addq $8, %rsp
269 ; CHECK-NEXT: .cfi_def_cfa_offset 24
270 ; CHECK-NEXT: popq %rbx
271 ; CHECK-NEXT: .cfi_def_cfa_offset 16
272 ; CHECK-NEXT: popq %rbp
273 ; CHECK-NEXT: .cfi_def_cfa_offset 8
276 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %a)]
277 br i1 %external_cond, label %left, label %right
280 %call1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
281 %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
282 call void @consume(ptr addrspace(1) %call1)
289 ; No need to check post-regalloc output as it is the same
290 define i1 @duplicate_reloc() gc "statepoint-example" {
291 ; CHECK-LABEL: duplicate_reloc:
292 ; CHECK: # %bb.0: # %entry
293 ; CHECK-NEXT: pushq %rax
294 ; CHECK-NEXT: .cfi_def_cfa_offset 16
295 ; CHECK-NEXT: callq func@PLT
296 ; CHECK-NEXT: .Ltmp8:
297 ; CHECK-NEXT: callq func@PLT
298 ; CHECK-NEXT: .Ltmp9:
299 ; CHECK-NEXT: movb $1, %al
300 ; CHECK-NEXT: popq %rcx
301 ; CHECK-NEXT: .cfi_def_cfa_offset 8
304 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) null, ptr addrspace(1) null)]
305 %base = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
306 %derived = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 1)
307 %safepoint_token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %base, ptr addrspace(1) %derived)]
308 %base_reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 0)
309 %derived_reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token2, i32 0, i32 1)
310 %cmp1 = icmp eq ptr addrspace(1) %base_reloc, null
311 %cmp2 = icmp eq ptr addrspace(1) %derived_reloc, null
312 %cmp = and i1 %cmp1, %cmp2
316 ; Vectors cannot go in VRegs
317 ; No need to check post-regalloc output as it is lowered using old scheme
318 define <2 x ptr addrspace(1)> @test_vector(<2 x ptr addrspace(1)> %obj) gc "statepoint-example" {
319 ; CHECK-LABEL: test_vector:
320 ; CHECK: # %bb.0: # %entry
321 ; CHECK-NEXT: subq $24, %rsp
322 ; CHECK-NEXT: .cfi_def_cfa_offset 32
323 ; CHECK-NEXT: movaps %xmm0, (%rsp)
324 ; CHECK-NEXT: callq func@PLT
325 ; CHECK-NEXT: .Ltmp10:
326 ; CHECK-NEXT: movaps (%rsp), %xmm0
327 ; CHECK-NEXT: addq $24, %rsp
328 ; CHECK-NEXT: .cfi_def_cfa_offset 8
331 %safepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (<2 x ptr addrspace(1)> %obj)]
332 %obj.relocated = call coldcc <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token %safepoint_token, i32 0, i32 0) ; (%obj, %obj)
333 ret <2 x ptr addrspace(1)> %obj.relocated
337 ; test limit on amount of vregs
338 define void @test_limit(ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %c, ptr addrspace(1) %d, ptr addrspace(1) %e) gc "statepoint-example" {
339 ; CHECK-LABEL: test_limit:
340 ; CHECK: # %bb.0: # %entry
341 ; CHECK-NEXT: pushq %r15
342 ; CHECK-NEXT: .cfi_def_cfa_offset 16
343 ; CHECK-NEXT: pushq %r14
344 ; CHECK-NEXT: .cfi_def_cfa_offset 24
345 ; CHECK-NEXT: pushq %r12
346 ; CHECK-NEXT: .cfi_def_cfa_offset 32
347 ; CHECK-NEXT: pushq %rbx
348 ; CHECK-NEXT: .cfi_def_cfa_offset 40
349 ; CHECK-NEXT: pushq %rax
350 ; CHECK-NEXT: .cfi_def_cfa_offset 48
351 ; CHECK-NEXT: .cfi_offset %rbx, -40
352 ; CHECK-NEXT: .cfi_offset %r12, -32
353 ; CHECK-NEXT: .cfi_offset %r14, -24
354 ; CHECK-NEXT: .cfi_offset %r15, -16
355 ; CHECK-NEXT: movq %r8, %rbx
356 ; CHECK-NEXT: movq %rcx, %r14
357 ; CHECK-NEXT: movq %rdx, %r15
358 ; CHECK-NEXT: movq %rsi, %r12
359 ; CHECK-NEXT: movq %rdi, (%rsp)
360 ; CHECK-NEXT: callq func@PLT
361 ; CHECK-NEXT: .Ltmp11:
362 ; CHECK-NEXT: movq (%rsp), %rdi
363 ; CHECK-NEXT: movq %r12, %rsi
364 ; CHECK-NEXT: movq %r15, %rdx
365 ; CHECK-NEXT: movq %r14, %rcx
366 ; CHECK-NEXT: movq %rbx, %r8
367 ; CHECK-NEXT: callq consume5@PLT
368 ; CHECK-NEXT: addq $8, %rsp
369 ; CHECK-NEXT: .cfi_def_cfa_offset 40
370 ; CHECK-NEXT: popq %rbx
371 ; CHECK-NEXT: .cfi_def_cfa_offset 32
372 ; CHECK-NEXT: popq %r12
373 ; CHECK-NEXT: .cfi_def_cfa_offset 24
374 ; CHECK-NEXT: popq %r14
375 ; CHECK-NEXT: .cfi_def_cfa_offset 16
376 ; CHECK-NEXT: popq %r15
377 ; CHECK-NEXT: .cfi_def_cfa_offset 8
380 %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %a, ptr addrspace(1) %b, ptr addrspace(1) %c, ptr addrspace(1) %d, ptr addrspace(1) %e)]
381 %rel1 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
382 %rel2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 1, i32 1)
383 %rel3 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 2, i32 2)
384 %rel4 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 3, i32 3)
385 %rel5 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 4, i32 4)
386 call void @consume5(ptr addrspace(1) %rel1, ptr addrspace(1) %rel2, ptr addrspace(1) %rel3, ptr addrspace(1) %rel4, ptr addrspace(1) %rel5)
390 ; test ISEL for constant base pointer - must properly tie operands
391 define void @test_const_base(ptr addrspace(1) %a) gc "statepoint-example" {
392 ; CHECK-LABEL: test_const_base:
393 ; CHECK: # %bb.0: # %entry
394 ; CHECK-NEXT: pushq %rbx
395 ; CHECK-NEXT: .cfi_def_cfa_offset 16
396 ; CHECK-NEXT: .cfi_offset %rbx, -16
397 ; CHECK-NEXT: movq %rdi, %rbx
398 ; CHECK-NEXT: callq func@PLT
399 ; CHECK-NEXT: .Ltmp12:
400 ; CHECK-NEXT: movq %rbx, %rdi
401 ; CHECK-NEXT: callq consume@PLT
402 ; CHECK-NEXT: popq %rbx
403 ; CHECK-NEXT: .cfi_def_cfa_offset 8
406 %token1 = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 0, i32 1, i32 7, ptr addrspace(1) null, i32 9), "gc-live" (ptr addrspace(1) null, ptr addrspace(1) %a)]
407 %rel = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token1, i32 0, i32 1)
408 call void @consume(ptr addrspace(1) %rel)
412 ; test multiple statepoints/relocates within single block.
413 ; relocates must be properly scheduled w.r.t. statepoints
414 define void @test_sched(float %0, i32 %1, ptr addrspace(1) %2) gc "statepoint-example" {
415 ; CHECK-LABEL: test_sched:
416 ; CHECK: # %bb.0: # %entry
417 ; CHECK-NEXT: pushq %rbp
418 ; CHECK-NEXT: .cfi_def_cfa_offset 16
419 ; CHECK-NEXT: pushq %rbx
420 ; CHECK-NEXT: .cfi_def_cfa_offset 24
421 ; CHECK-NEXT: subq $24, %rsp
422 ; CHECK-NEXT: .cfi_def_cfa_offset 48
423 ; CHECK-NEXT: .cfi_offset %rbx, -24
424 ; CHECK-NEXT: .cfi_offset %rbp, -16
425 ; CHECK-NEXT: movq %rsi, %rbx
426 ; CHECK-NEXT: movl %edi, %ebp
427 ; CHECK-NEXT: movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
428 ; CHECK-NEXT: callq consume3@PLT
429 ; CHECK-NEXT: .Ltmp13:
430 ; CHECK-NEXT: xorps %xmm0, %xmm0
431 ; CHECK-NEXT: cvtsi2sd %ebp, %xmm0
432 ; CHECK-NEXT: movsd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
433 ; CHECK-NEXT: nopl 8(%rax,%rax)
434 ; CHECK-NEXT: .Ltmp14:
435 ; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload
436 ; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero
437 ; CHECK-NEXT: movss %xmm0, (%rsp)
438 ; CHECK-NEXT: movsd {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 8-byte Reload
439 ; CHECK-NEXT: # xmm0 = mem[0],zero
440 ; CHECK-NEXT: movsd %xmm0, {{[0-9]+}}(%rsp)
441 ; CHECK-NEXT: nopl 8(%rax,%rax)
442 ; CHECK-NEXT: .Ltmp15:
443 ; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload
444 ; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero
445 ; CHECK-NEXT: movss %xmm0, (%rsp)
446 ; CHECK-NEXT: movsd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 8-byte Reload
447 ; CHECK-NEXT: # xmm1 = mem[0],zero
448 ; CHECK-NEXT: movsd %xmm1, {{[0-9]+}}(%rsp)
449 ; CHECK-NEXT: nopl 8(%rax,%rax)
450 ; CHECK-NEXT: .Ltmp16:
451 ; CHECK-NEXT: xorl %eax, %eax
452 ; CHECK-NEXT: xorpd %xmm0, %xmm0
453 ; CHECK-NEXT: movsd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 8-byte Reload
454 ; CHECK-NEXT: # xmm1 = mem[0],zero
455 ; CHECK-NEXT: ucomisd %xmm0, %xmm1
456 ; CHECK-NEXT: movabsq $9223372036854775807, %rdi # imm = 0x7FFFFFFFFFFFFFFF
457 ; CHECK-NEXT: cmovbeq %rax, %rdi
458 ; CHECK-NEXT: movsd %xmm1, {{[0-9]+}}(%rsp)
459 ; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload
460 ; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero
461 ; CHECK-NEXT: movss %xmm0, (%rsp)
462 ; CHECK-NEXT: nopl 8(%rax,%rax)
463 ; CHECK-NEXT: .Ltmp17:
464 ; CHECK-NEXT: addq $24, %rsp
465 ; CHECK-NEXT: .cfi_def_cfa_offset 24
466 ; CHECK-NEXT: popq %rbx
467 ; CHECK-NEXT: .cfi_def_cfa_offset 16
468 ; CHECK-NEXT: popq %rbp
469 ; CHECK-NEXT: .cfi_def_cfa_offset 8
472 %token0 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 0, ptr nonnull elementtype(void (float)) @consume3, i32 1, i32 0, float %0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) %2) ]
473 %reloc1 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token0, i32 0, i32 0) ; (%2, %2)
474 %tmp1 = sitofp i32 %1 to double
475 %to_max.i29 = fcmp ogt double %tmp1, 0.000000e+00
476 %token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 5, ptr nonnull elementtype(i32 (i32)) @consume1, i32 1, i32 0, i32 undef, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) %reloc1) ]
477 %reloc2 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token1, i32 0, i32 0) ; (%reloc1, %reloc1)
478 %reloc3 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token1, i32 0, i32 0) ; (%reloc1, %reloc1)
479 %token2 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 5, ptr nonnull elementtype(i32 (i32)) @consume1, i32 1, i32 0, i32 undef, i32 0, i32 0) [ "deopt"(float %0, double %tmp1), "gc-live"(ptr addrspace(1) %reloc2, ptr addrspace(1) %reloc3) ]
480 %reloc4 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token2, i32 0, i32 0) ; (%reloc3, %reloc2)
481 %reloc5 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token2, i32 1, i32 1) ; (%reloc3, %reloc3)
482 %token3 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 5, ptr nonnull elementtype(void (float)) @consume3, i32 1, i32 0, float %0, i32 0, i32 0) [ "deopt"(float %0, double %tmp1), "gc-live"(ptr addrspace(1) %reloc4, ptr addrspace(1) %reloc5) ]
483 %reloc6 = call coldcc ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token3, i32 1, i32 0) ; (%reloc5, %reloc4)
484 %tmp5 = select i1 %to_max.i29, i64 9223372036854775807, i64 0
485 %token4 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2, i32 5, ptr nonnull elementtype(float (i64)) @consume4, i32 1, i32 0, i64 %tmp5, i32 0, i32 0) [ "deopt"(float %0, double %tmp1), "gc-live"() ]
489 declare token @llvm.experimental.gc.statepoint.p0(i64 immarg, i32 immarg, ptr, i32 immarg, i32 immarg, ...)
490 declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32)
491 declare <2 x ptr addrspace(1)> @llvm.experimental.gc.relocate.v2p1(token, i32, i32)
492 declare i1 @llvm.experimental.gc.result.i1(token)