Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / statepoint-stackmap-format.ll
blob1d45c7db84f8185efa7f09213afdeae1dc8d4fc6
1 ; RUN: llc < %s -verify-machineinstrs -stack-symbol-ordering=0 -mtriple="x86_64-pc-linux-gnu" | FileCheck %s
2 ; RUN: llc < %s -verify-machineinstrs -stack-symbol-ordering=0 -mtriple="x86_64-pc-unknown-elf" | FileCheck %s
4 ; This test is a basic correctness check to ensure statepoints are generating
5 ; StackMap sections correctly.  This is not intended to be a rigorous test of
6 ; the StackMap format (see the stackmap tests for that).
8 target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
10 declare zeroext i1 @return_i1()
12 define i1 @test(ptr addrspace(1) %ptr_base, i32 %arg)
13   gc "statepoint-example" {
14 ; CHECK-LABEL: test:
15 ; Do we see two spills for the local values and the store to the
16 ; alloca?
17 ; CHECK: subq   $40, %rsp
18 ; CHECK: movq   $0,   24(%rsp)
19 ; CHECK: movq   %rdi, 16(%rsp)
20 ; CHECK: movq   %rax, 8(%rsp)
21 ; CHECK: callq return_i1
22 ; CHECK: addq   $40, %rsp
23 ; CHECK: retq
24 entry:
25   %metadata1 = alloca ptr addrspace(1), i32 2, align 8
26   store ptr addrspace(1) null, ptr %metadata1
27   %ptr_derived = getelementptr i32, ptr addrspace(1) %ptr_base, i32 %arg
28   %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) %ptr_base, ptr addrspace(1) %ptr_derived, ptr addrspace(1) null), "deopt" (ptr addrspace(1) %ptr_base, ptr addrspace(1) null)]
29   %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
30   %a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
31   %b = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 1)
32   %c = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 2, i32 2)
33
34   ret i1 %call1
37 ; This is similar to the previous test except that we have derived pointer as
38 ; argument to the function. Despite that this can not happen after the
39 ; RewriteSafepointForGC pass, lowering should be able to handle it anyway.
40 define i1 @test_derived_arg(ptr addrspace(1) %ptr_base,
41                             ptr addrspace(1) %ptr_derived)
42   gc "statepoint-example" {
43 ; CHECK-LABEL: test_derived_arg
44 ; Do we see two spills for the local values and the store to the
45 ; alloca?
46 ; CHECK: subq   $40, %rsp
47 ; CHECK: movq   $0,   24(%rsp)
48 ; CHECK: movq   %rdi, 16(%rsp)
49 ; CHECK: movq   %rsi, 8(%rsp)
50 ; CHECK: callq return_i1
51 ; CHECK: addq   $40, %rsp
52 ; CHECK: retq
53 entry:
54   %metadata1 = alloca ptr addrspace(1), i32 2, align 8
55   store ptr addrspace(1) null, ptr %metadata1
56   %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) %ptr_base, ptr addrspace(1) %ptr_derived, ptr addrspace(1) null), "deopt" (ptr addrspace(1) %ptr_base, ptr addrspace(1) null)]
57   %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
58   %a = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 0)
59   %b = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 0, i32 1)
60   %c = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token, i32 2, i32 2)
61
62   ret i1 %call1
65 ; Simple test case to check that we emit the ID field correctly
66 define i1 @test_id() gc "statepoint-example" {
67 ; CHECK-LABEL: test_id
68 entry:
69   %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 237, i32 0, ptr elementtype(i1 ()) @return_i1, i32 0, i32 0, i32 0, i32 0)
70   %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
71   ret i1 %call1
74 ; This test checks that when SP is changed in the function
75 ; (e.g. passing arguments on stack), the stack map entry
76 ; takes this adjustment into account.
77 declare void @many_arg(i64, i64, i64, i64, i64, i64, i64, i64)
79 define i32 @test_spadj(ptr addrspace(1) %p) gc "statepoint-example" {
80   ; CHECK-LABEL: test_spadj
81   ; CHECK: movq %rdi, (%rsp)
82   ; CHECK: xorl %edi, %edi
83   ; CHECK: xorl %esi, %esi
84   ; CHECK: xorl %edx, %edx
85   ; CHECK: xorl %ecx, %ecx
86   ; CHECK: xorl %r8d, %r8d
87   ; CHECK: xorl %r9d, %r9d
88   ; CHECK: pushq $0
89   ; CHECK: pushq $0
90   ; CHECK: callq many_arg
91   ; CHECK: addq $16, %rsp
92   ; CHECK: movq (%rsp)
93   %statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (i64, i64, i64, i64, i64, i64, i64, i64)) @many_arg, i32 8, i32 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %p)]
94   %p.relocated = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %statepoint_token, i32 0, i32 0) ; (%p, %p)
95   %ld = load i32, ptr addrspace(1) %p.relocated
96   ret i32 %ld
99 ; Test that function arguments at fixed stack offset
100 ; can be directly encoded in the stack map, without
101 ; spilling.
102 %struct = type { i64, i64, i64 }
104 declare void @use(ptr)
106 define void @test_fixed_arg(ptr byval(%struct) %x) gc "statepoint-example" {
107 ; CHECK-LABEL: test_fixed_arg
108 ; CHECK: pushq %rax
109 ; CHECK: leaq 16(%rsp), %rdi
110 ; Should not spill fixed stack address.
111 ; CHECK-NOT: movq %rdi, (%rsp)
112 ; CHECK: callq use
113 ; CHECK: popq %rax
114 ; CHECK: retq
115 entry:
116   br label %bb
118 bb:                                               ; preds = %entry
119   %statepoint_token = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (ptr)) @use, i32 1, i32 0, ptr %x, i32 0, i32 0) ["deopt" (ptr %x)]
120   ret void
123 declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)
124 declare i1 @llvm.experimental.gc.result.i1(token)
125 declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32) #3
127 ; CHECK-LABEL: .section .llvm_stackmaps
128 ; CHECK-NEXT:  __LLVM_StackMaps:
129 ; Header
130 ; CHECK-NEXT:   .byte 3
131 ; CHECK-NEXT:   .byte 0
132 ; CHECK-NEXT:   .short 0
133 ; Num Functions
134 ; CHECK-NEXT:   .long 5
135 ; Num LargeConstants
136 ; CHECK-NEXT:   .long 0
137 ; Num Callsites
138 ; CHECK-NEXT:   .long 5
140 ; Functions and stack size
141 ; CHECK-NEXT:   .quad test
142 ; CHECK-NEXT:   .quad 40
143 ; CHECK-NEXT:   .quad 1
144 ; CHECK-NEXT:   .quad test_derived_arg
145 ; CHECK-NEXT:   .quad 40
146 ; CHECK-NEXT:   .quad 1
147 ; CHECK-NEXT:   .quad test_id
148 ; CHECK-NEXT:   .quad 8
149 ; CHECK-NEXT:   .quad 1
150 ; CHECK-NEXT:   .quad test_spadj
151 ; CHECK-NEXT:   .quad 8
152 ; CHECK-NEXT:   .quad 1
153 ; CHECK-NEXT:   .quad test_fixed_arg
154 ; CHECK-NEXT:   .quad 8
155 ; CHECK-NEXT:   .quad 1
158 ; test
161 ; Statepoint ID
162 ; CHECK-NEXT: .quad     0
164 ; Callsites
165 ; Constant arguments
166 ; CHECK-NEXT: .long     .Ltmp0-test
167 ; CHECK: .short 0
168 ; CHECK: .short 11
169 ; SmallConstant (0)
170 ; CHECK: .byte  4
171 ; CHECK-NEXT:   .byte   0
172 ; CHECK: .short 8
173 ; CHECK: .short 0
174 ; CHECK-NEXT:   .short  0
175 ; CHECK: .long  0
176 ; SmallConstant (0)
177 ; CHECK: .byte  4
178 ; CHECK-NEXT:   .byte   0
179 ; CHECK: .short 8
180 ; CHECK: .short 0
181 ; CHECK-NEXT:   .short  0
182 ; CHECK: .long  0
183 ; SmallConstant (2)
184 ; CHECK: .byte  4
185 ; CHECK-NEXT:   .byte   0
186 ; CHECK: .short 8
187 ; CHECK: .short 0
188 ; CHECK-NEXT:   .short  0
189 ; CHECK: .long  2
190 ; Indirect Spill Slot [RSP+0]
191 ; CHECK: .byte  3
192 ; CHECK-NEXT:   .byte   0
193 ; CHECK: .short 8
194 ; CHECK: .short 7
195 ; CHECK-NEXT:   .short  0
196 ; CHECK: .long  16
197 ; SmallConstant  (0)
198 ; CHECK: .byte  4
199 ; CHECK-NEXT:   .byte   0
200 ; CHECK: .short 8
201 ; CHECK: .short 0
202 ; CHECK-NEXT:   .short  0
203 ; CHECK: .long  0
204 ; SmallConstant  (0)
205 ; CHECK: .byte  4
206 ; CHECK-NEXT:   .byte   0
207 ; CHECK: .short 8
208 ; CHECK: .short 0
209 ; CHECK-NEXT:   .short  0
210 ; CHECK: .long  0
211 ; SmallConstant  (0)
212 ; CHECK: .byte  4
213 ; CHECK-NEXT:   .byte   0
214 ; CHECK: .short 8
215 ; CHECK: .short 0
216 ; CHECK-NEXT:   .short  0
217 ; CHECK: .long  0
218 ; Indirect Spill Slot [RSP+16]
219 ; CHECK: .byte  3
220 ; CHECK-NEXT:   .byte   0
221 ; CHECK: .short 8
222 ; CHECK: .short 7
223 ; CHECK-NEXT:   .short  0
224 ; CHECK: .long  16
225 ; Indirect Spill Slot [RSP+8]
226 ; CHECK: .byte  3
227 ; CHECK-NEXT:   .byte   0
228 ; CHECK: .short 8
229 ; CHECK: .short 7
230 ; CHECK-NEXT:   .short  0
231 ; CHECK: .long  8
232 ; Indirect Spill Slot [RSP+16]
233 ; CHECK: .byte  3
234 ; CHECK-NEXT:   .byte   0
235 ; CHECK: .short 8
236 ; CHECK: .short 7
237 ; CHECK-NEXT:   .short  0
238 ; CHECK: .long  16
239 ; Indirect Spill Slot [RSP+16]
240 ; CHECK: .byte  3
241 ; CHECK-NEXT:   .byte   0
242 ; CHECK: .short 8
243 ; CHECK: .short 7
244 ; CHECK-NEXT:   .short  0
245 ; CHECK: .long  16
247 ; No Padding or LiveOuts
248 ; CHECK: .short 0
249 ; CHECK: .short 0
250 ; CHECK: .p2align       3
253 ; test_derived_arg
255 ; Statepoint ID
256 ; CHECK-NEXT: .quad     0
258 ; Callsites
259 ; Constant arguments
260 ; CHECK-NEXT: .long     .Ltmp1-test_derived_arg
261 ; CHECK: .short 0
262 ; CHECK: .short 11
263 ; SmallConstant (0)
264 ; CHECK: .byte  4
265 ; CHECK-NEXT:   .byte   0
266 ; CHECK: .short 8
267 ; CHECK: .short 0
268 ; CHECK-NEXT:   .short  0
269 ; CHECK: .long  0
270 ; SmallConstant (2)
271 ; CHECK: .byte  4
272 ; CHECK-NEXT:   .byte   0
273 ; CHECK: .short 8
274 ; CHECK: .short 0
275 ; CHECK-NEXT:   .short  0
276 ; CHECK: .long  2
277 ; Indirect Spill Slot [RSP+0]
278 ; CHECK: .byte  3
279 ; CHECK-NEXT:   .byte   0
280 ; CHECK: .short 8
281 ; CHECK: .short 7
282 ; CHECK-NEXT:   .short  0
283 ; CHECK: .long  16
284 ; SmallConstant  (0)
285 ; CHECK: .byte  4
286 ; CHECK-NEXT:   .byte   0
287 ; CHECK: .short 8
288 ; CHECK: .short 0
289 ; CHECK-NEXT:   .short  0
290 ; CHECK: .long  0
291 ; SmallConstant  (0)
292 ; CHECK: .byte  4
293 ; CHECK-NEXT:   .byte   0
294 ; CHECK: .short 8
295 ; CHECK: .short 0
296 ; CHECK-NEXT:   .short  0
297 ; CHECK: .long  0
298 ; SmallConstant  (0)
299 ; CHECK: .byte  4
300 ; CHECK-NEXT:   .byte   0
301 ; CHECK: .short 8
302 ; CHECK: .short 0
303 ; CHECK-NEXT:   .short  0
304 ; CHECK: .long  0
305 ; Indirect Spill Slot [RSP+16]
306 ; CHECK: .byte  3
307 ; CHECK-NEXT:   .byte   0
308 ; CHECK: .short 8
309 ; CHECK: .short 7
310 ; CHECK-NEXT:   .short  0
311 ; CHECK: .long  16
312 ; Indirect Spill Slot [RSP+8]
313 ; CHECK: .byte  3
314 ; CHECK-NEXT:   .byte   0
315 ; CHECK: .short 8
316 ; CHECK: .short 7
317 ; CHECK-NEXT:   .short  0
318 ; CHECK: .long  8
319 ; Indirect Spill Slot [RSP+16]
320 ; CHECK: .byte  3
321 ; CHECK-NEXT:   .byte   0
322 ; CHECK: .short 8
323 ; CHECK: .short 7
324 ; CHECK-NEXT:   .short  0
325 ; CHECK: .long  16
326 ; Indirect Spill Slot [RSP+16]
327 ; CHECK: .byte  3
328 ; CHECK-NEXT:   .byte   0
329 ; CHECK: .short 8
330 ; CHECK: .short 7
331 ; CHECK-NEXT:   .short  0
332 ; CHECK: .long  16
334 ; No Padding or LiveOuts
335 ; CHECK: .short 0
336 ; CHECK: .short 0
337 ; CHECK: .p2align       3
339 ; Records for the test_id function:
341 ; The Statepoint ID:
342 ; CHECK-NEXT: .quad     237
344 ; Instruction Offset
345 ; CHECK-NEXT: .long     .Ltmp2-test_id
347 ; Reserved:
348 ; CHECK: .short 0
350 ; NumLocations:
351 ; CHECK: .short 3
353 ; StkMapRecord[0]:
354 ; SmallConstant(0):
355 ; CHECK: .byte  4
356 ; CHECK-NEXT:   .byte   0
357 ; CHECK: .short 8
358 ; CHECK: .short 0
359 ; CHECK-NEXT:   .short  0
360 ; CHECK: .long  0
362 ; StkMapRecord[1]:
363 ; SmallConstant(0):
364 ; CHECK: .byte  4
365 ; CHECK-NEXT:   .byte   0
366 ; CHECK: .short 8
367 ; CHECK: .short 0
368 ; CHECK-NEXT:   .short  0
369 ; CHECK: .long  0
371 ; StkMapRecord[2]:
372 ; SmallConstant(0):
373 ; CHECK: .byte  4
374 ; CHECK-NEXT:   .byte   0
375 ; CHECK: .short 8
376 ; CHECK: .short 0
377 ; CHECK-NEXT:   .short  0
378 ; CHECK: .long  0
380 ; No padding or LiveOuts
381 ; CHECK: .short 0
382 ; CHECK: .short 0
383 ; CHECK: .p2align       3
386 ; test_spadj
388 ; Statepoint ID
389 ; CHECK-NEXT: .quad     0
391 ; Instruction Offset
392 ; CHECK-NEXT: .long     .Ltmp3-test_spadj
394 ; Reserved:
395 ; CHECK: .short 0
397 ; NumLocations:
398 ; CHECK: .short 5
400 ; StkMapRecord[0]:
401 ; SmallConstant(0):
402 ; CHECK: .byte  4
403 ; CHECK-NEXT:   .byte   0
404 ; CHECK: .short 8
405 ; CHECK: .short 0
406 ; CHECK-NEXT:   .short  0
407 ; CHECK: .long  0
409 ; StkMapRecord[1]:
410 ; SmallConstant(0):
411 ; CHECK: .byte  4
412 ; CHECK-NEXT:   .byte   0
413 ; CHECK: .short 8
414 ; CHECK: .short 0
415 ; CHECK-NEXT:   .short  0
416 ; CHECK: .long  0
418 ; StkMapRecord[2]:
419 ; SmallConstant(0):
420 ; CHECK: .byte  4
421 ; CHECK-NEXT:   .byte   0
422 ; CHECK: .short 8
423 ; CHECK: .short 0
424 ; CHECK-NEXT:   .short  0
425 ; CHECK: .long  0
427 ; StkMapRecord[3]:
428 ; Indirect Spill Slot [RSP+16]
429 ; CHECK: .byte  3
430 ; CHECK-NEXT:   .byte   0
431 ; CHECK: .short 8
432 ; CHECK: .short 7
433 ; CHECK-NEXT:   .short  0
434 ; CHECK: .long  16
436 ; StkMapRecord[4]:
437 ; Indirect Spill Slot [RSP+16]
438 ; CHECK: .byte  3
439 ; CHECK-NEXT:   .byte   0
440 ; CHECK: .short 8
441 ; CHECK: .short 7
442 ; CHECK-NEXT:   .short  0
443 ; CHECK: .long  16
445 ; No padding or LiveOuts
446 ; CHECK: .short 0
447 ; CHECK: .short 0
448 ; CHECK: .p2align       3
451 ; test_fixed_arg
453 ; Statepoint ID
454 ; CHECK-NEXT: .quad     0
456 ; Instruction Offset
457 ; CHECK-NEXT: .long     .Ltmp4-test_fixed_arg
459 ; Reserved:
460 ; CHECK: .short 0
462 ; NumLocations:
463 ; CHECK: .short 4
465 ; StkMapRecord[0]:
466 ; SmallConstant(0):
467 ; CHECK: .byte  4
468 ; CHECK-NEXT:   .byte   0
469 ; CHECK: .short 8
470 ; CHECK: .short 0
471 ; CHECK-NEXT:   .short  0
472 ; CHECK: .long  0
474 ; StkMapRecord[1]:
475 ; SmallConstant(0):
476 ; CHECK: .byte  4
477 ; CHECK-NEXT:   .byte   0
478 ; CHECK: .short 8
479 ; CHECK: .short 0
480 ; CHECK-NEXT:   .short  0
481 ; CHECK: .long  0
483 ; StkMapRecord[2]:
484 ; SmallConstant(1):
485 ; CHECK: .byte  4
486 ; CHECK-NEXT:   .byte   0
487 ; CHECK: .short 8
488 ; CHECK: .short 0
489 ; CHECK-NEXT:   .short  0
490 ; CHECK: .long  1
492 ; StkMapRecord[3]:
493 ; Direct RSP+16
494 ; CHECK: .byte  2
495 ; CHECK-NEXT:   .byte   0
496 ; CHECK: .short 8
497 ; CHECK: .short 7
498 ; CHECK-NEXT:   .short  0
499 ; CHECK: .long  16
501 ; No padding or LiveOuts
502 ; CHECK: .short 0
503 ; CHECK: .short 0
504 ; CHECK: .p2align       3