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
3
4; This test is a sanity check to ensure statepoints are generating StackMap
5; sections correctly.  This is not intended to be a rigorous test of the
6; StackMap format (see the stackmap tests for that).
7
8target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
9
10declare zeroext i1 @return_i1()
11
12define i1 @test(i32 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
24entry:
25  %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
26  store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
27  %ptr_derived = getelementptr i32, i32 addrspace(1)* %ptr_base, i32 %arg
28  %safepoint_token = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
29  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
30  %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 9, i32 9)
31  %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 9, i32 10)
32  %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 11, i32 11)
33;
34  ret i1 %call1
35}
36
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.
40define i1 @test_derived_arg(i32 addrspace(1)* %ptr_base,
41                            i32 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
53entry:
54  %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
55  store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
56  %safepoint_token = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null)
57  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(token %safepoint_token)
58  %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 9, i32 9)
59  %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 9, i32 10)
60  %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %safepoint_token, i32 11, i32 11)
61;
62  ret i1 %call1
63}
64
65; Simple test case to check that we emit the ID field correctly
66define i1 @test_id() gc "statepoint-example" {
67; CHECK-LABEL: test_id
68entry:
69  %safepoint_token = tail call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 237, i32 0, 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
72}
73
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.
77declare void @many_arg(i64, i64, i64, i64, i64, i64, i64, i64)
78
79define i32 @test_spadj(i32 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, void (i64, i64, i64, i64, i64, i64, i64, i64)*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidi64i64i64i64i64i64i64i64f(i64 0, i32 0, 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, i32 addrspace(1)* %p)
94  %p.relocated = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %statepoint_token, i32 15, i32 15) ; (%p, %p)
95  %ld = load i32, i32 addrspace(1)* %p.relocated
96  ret i32 %ld
97}
98
99
100declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
101declare token @llvm.experimental.gc.statepoint.p0f_isVoidi64i64i64i64i64i64i64i64f(i64, i32, void (i64, i64, i64, i64, i64, i64, i64, i64)*, i32, i32, ...)
102declare i1 @llvm.experimental.gc.result.i1(token)
103declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) #3
104
105; CHECK-LABEL: .section .llvm_stackmaps
106; CHECK-NEXT:  __LLVM_StackMaps:
107; Header
108; CHECK-NEXT:   .byte 3
109; CHECK-NEXT:   .byte 0
110; CHECK-NEXT:   .short 0
111; Num Functions
112; CHECK-NEXT:   .long 4
113; Num LargeConstants
114; CHECK-NEXT:   .long 0
115; Num Callsites
116; CHECK-NEXT:   .long 4
117
118; Functions and stack size
119; CHECK-NEXT:   .quad test
120; CHECK-NEXT:   .quad 40
121; CHECK-NEXT:   .quad 1
122; CHECK-NEXT:   .quad test_derived_arg
123; CHECK-NEXT:   .quad 40
124; CHECK-NEXT:   .quad 1
125; CHECK-NEXT:   .quad test_id
126; CHECK-NEXT:   .quad 8
127; CHECK-NEXT:   .quad 1
128; CHECK-NEXT:   .quad test_spadj
129; CHECK-NEXT:   .quad 8
130; CHECK-NEXT:   .quad 1
131
132;
133; test
134;
135
136; Statepoint ID
137; CHECK-NEXT: .quad	0
138
139; Callsites
140; Constant arguments
141; CHECK-NEXT: .long	.Ltmp0-test
142; CHECK: .short	0
143; CHECK: .short	11
144; SmallConstant (0)
145; CHECK: .byte	4
146; CHECK-NEXT:   .byte   0
147; CHECK: .short 8
148; CHECK: .short	0
149; CHECK-NEXT:   .short  0
150; CHECK: .long	0
151; SmallConstant (0)
152; CHECK: .byte	4
153; CHECK-NEXT:   .byte   0
154; CHECK: .short 8
155; CHECK: .short	0
156; CHECK-NEXT:   .short  0
157; CHECK: .long	0
158; SmallConstant (2)
159; CHECK: .byte	4
160; CHECK-NEXT:   .byte   0
161; CHECK: .short 8
162; CHECK: .short	0
163; CHECK-NEXT:   .short  0
164; CHECK: .long	2
165; Indirect Spill Slot [RSP+0]
166; CHECK: .byte	3
167; CHECK-NEXT:   .byte   0
168; CHECK: .short 8
169; CHECK: .short	7
170; CHECK-NEXT:   .short  0
171; CHECK: .long	16
172; SmallConstant  (0)
173; CHECK: .byte	4
174; CHECK-NEXT:   .byte   0
175; CHECK: .short 8
176; CHECK: .short	0
177; CHECK-NEXT:   .short  0
178; CHECK: .long	0
179; SmallConstant  (0)
180; CHECK: .byte	4
181; CHECK-NEXT:   .byte   0
182; CHECK: .short 8
183; CHECK: .short	0
184; CHECK-NEXT:   .short  0
185; CHECK: .long	0
186; SmallConstant  (0)
187; CHECK: .byte	4
188; CHECK-NEXT:   .byte   0
189; CHECK: .short 8
190; CHECK: .short	0
191; CHECK-NEXT:   .short  0
192; CHECK: .long	0
193; Indirect Spill Slot [RSP+16]
194; CHECK: .byte	3
195; CHECK-NEXT:   .byte   0
196; CHECK: .short 8
197; CHECK: .short	7
198; CHECK-NEXT:   .short  0
199; CHECK: .long	16
200; Indirect Spill Slot [RSP+8]
201; CHECK: .byte	3
202; CHECK-NEXT:   .byte   0
203; CHECK: .short 8
204; CHECK: .short	7
205; CHECK-NEXT:   .short  0
206; CHECK: .long	8
207; Indirect Spill Slot [RSP+16]
208; CHECK: .byte	3
209; CHECK-NEXT:   .byte   0
210; CHECK: .short 8
211; CHECK: .short	7
212; CHECK-NEXT:   .short  0
213; CHECK: .long	16
214; Indirect Spill Slot [RSP+16]
215; CHECK: .byte	3
216; CHECK-NEXT:   .byte   0
217; CHECK: .short 8
218; CHECK: .short	7
219; CHECK-NEXT:   .short  0
220; CHECK: .long	16
221
222; No Padding or LiveOuts
223; CHECK: .short	0
224; CHECK: .short	0
225; CHECK: .p2align	3
226
227;
228; test_derived_arg
229
230; Statepoint ID
231; CHECK-NEXT: .quad	0
232
233; Callsites
234; Constant arguments
235; CHECK-NEXT: .long	.Ltmp1-test_derived_arg
236; CHECK: .short	0
237; CHECK: .short	11
238; SmallConstant (0)
239; CHECK: .byte	4
240; CHECK-NEXT:   .byte   0
241; CHECK: .short 8
242; CHECK: .short	0
243; CHECK-NEXT:   .short  0
244; CHECK: .long	0
245; SmallConstant (2)
246; CHECK: .byte	4
247; CHECK-NEXT:   .byte   0
248; CHECK: .short 8
249; CHECK: .short	0
250; CHECK-NEXT:   .short  0
251; CHECK: .long	2
252; Indirect Spill Slot [RSP+0]
253; CHECK: .byte	3
254; CHECK-NEXT:   .byte   0
255; CHECK: .short 8
256; CHECK: .short	7
257; CHECK-NEXT:   .short  0
258; CHECK: .long	16
259; SmallConstant  (0)
260; CHECK: .byte	4
261; CHECK-NEXT:   .byte   0
262; CHECK: .short 8
263; CHECK: .short	0
264; CHECK-NEXT:   .short  0
265; CHECK: .long	0
266; SmallConstant  (0)
267; CHECK: .byte	4
268; CHECK-NEXT:   .byte   0
269; CHECK: .short 8
270; CHECK: .short	0
271; CHECK-NEXT:   .short  0
272; CHECK: .long	0
273; SmallConstant  (0)
274; CHECK: .byte	4
275; CHECK-NEXT:   .byte   0
276; CHECK: .short 8
277; CHECK: .short	0
278; CHECK-NEXT:   .short  0
279; CHECK: .long	0
280; Indirect Spill Slot [RSP+16]
281; CHECK: .byte	3
282; CHECK-NEXT:   .byte   0
283; CHECK: .short 8
284; CHECK: .short	7
285; CHECK-NEXT:   .short  0
286; CHECK: .long	16
287; Indirect Spill Slot [RSP+8]
288; CHECK: .byte	3
289; CHECK-NEXT:   .byte   0
290; CHECK: .short 8
291; CHECK: .short	7
292; CHECK-NEXT:   .short  0
293; CHECK: .long	8
294; Indirect Spill Slot [RSP+16]
295; CHECK: .byte	3
296; CHECK-NEXT:   .byte   0
297; CHECK: .short 8
298; CHECK: .short	7
299; CHECK-NEXT:   .short  0
300; CHECK: .long	16
301; Indirect Spill Slot [RSP+16]
302; CHECK: .byte	3
303; CHECK-NEXT:   .byte   0
304; CHECK: .short 8
305; CHECK: .short	7
306; CHECK-NEXT:   .short  0
307; CHECK: .long	16
308
309; No Padding or LiveOuts
310; CHECK: .short	0
311; CHECK: .short	0
312; CHECK: .p2align	3
313
314; Records for the test_id function:
315
316; The Statepoint ID:
317; CHECK-NEXT: .quad	237
318
319; Instruction Offset
320; CHECK-NEXT: .long	.Ltmp2-test_id
321
322; Reserved:
323; CHECK: .short	0
324
325; NumLocations:
326; CHECK: .short	3
327
328; StkMapRecord[0]:
329; SmallConstant(0):
330; CHECK: .byte	4
331; CHECK-NEXT:   .byte   0
332; CHECK: .short 8
333; CHECK: .short	0
334; CHECK-NEXT:   .short  0
335; CHECK: .long	0
336
337; StkMapRecord[1]:
338; SmallConstant(0):
339; CHECK: .byte	4
340; CHECK-NEXT:   .byte   0
341; CHECK: .short 8
342; CHECK: .short	0
343; CHECK-NEXT:   .short  0
344; CHECK: .long	0
345
346; StkMapRecord[2]:
347; SmallConstant(0):
348; CHECK: .byte	4
349; CHECK-NEXT:   .byte   0
350; CHECK: .short 8
351; CHECK: .short	0
352; CHECK-NEXT:   .short  0
353; CHECK: .long	0
354
355; No padding or LiveOuts
356; CHECK: .short	0
357; CHECK: .short	0
358; CHECK: .p2align	3
359
360;
361; test_spadj
362
363; Statepoint ID
364; CHECK-NEXT: .quad	0
365
366; Instruction Offset
367; CHECK-NEXT: .long	.Ltmp3-test_spadj
368
369; Reserved:
370; CHECK: .short	0
371
372; NumLocations:
373; CHECK: .short	5
374
375; StkMapRecord[0]:
376; SmallConstant(0):
377; CHECK: .byte	4
378; CHECK-NEXT:   .byte   0
379; CHECK: .short 8
380; CHECK: .short	0
381; CHECK-NEXT:   .short  0
382; CHECK: .long	0
383
384; StkMapRecord[1]:
385; SmallConstant(0):
386; CHECK: .byte	4
387; CHECK-NEXT:   .byte   0
388; CHECK: .short 8
389; CHECK: .short	0
390; CHECK-NEXT:   .short  0
391; CHECK: .long	0
392
393; StkMapRecord[2]:
394; SmallConstant(0):
395; CHECK: .byte	4
396; CHECK-NEXT:   .byte   0
397; CHECK: .short 8
398; CHECK: .short	0
399; CHECK-NEXT:   .short  0
400; CHECK: .long	0
401
402; StkMapRecord[3]:
403; Indirect Spill Slot [RSP+16]
404; CHECK: .byte	3
405; CHECK-NEXT:   .byte   0
406; CHECK: .short 8
407; CHECK: .short	7
408; CHECK-NEXT:   .short  0
409; CHECK: .long	16
410
411; StkMapRecord[4]:
412; Indirect Spill Slot [RSP+16]
413; CHECK: .byte	3
414; CHECK-NEXT:   .byte   0
415; CHECK: .short 8
416; CHECK: .short	7
417; CHECK-NEXT:   .short  0
418; CHECK: .long	16
419
420; No padding or LiveOuts
421; CHECK: .short	0
422; CHECK: .short	0
423; CHECK: .p2align	3
424