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
75declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
76declare i1 @llvm.experimental.gc.result.i1(token)
77declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32) #3
78
79; CHECK-LABEL: .section .llvm_stackmaps
80; CHECK-NEXT:  __LLVM_StackMaps:
81; Header
82; CHECK-NEXT:   .byte 3
83; CHECK-NEXT:   .byte 0
84; CHECK-NEXT:   .short 0
85; Num Functions
86; CHECK-NEXT:   .long 3
87; Num LargeConstants
88; CHECK-NEXT:   .long 0
89; Num Callsites
90; CHECK-NEXT:   .long 3
91
92; Functions and stack size
93; CHECK-NEXT:   .quad test
94; CHECK-NEXT:   .quad 40
95; CHECK-NEXT:   .quad 1
96; CHECK-NEXT:   .quad test_derived_arg
97; CHECK-NEXT:   .quad 40
98; CHECK-NEXT:   .quad 1
99; CHECK-NEXT:   .quad test_id
100; CHECK-NEXT:   .quad 8
101; CHECK-NEXT:   .quad 1
102
103;
104; test
105;
106
107; Statepoint ID
108; CHECK-NEXT: .quad	0
109
110; Callsites
111; Constant arguments
112; CHECK-NEXT: .long	.Ltmp0-test
113; CHECK: .short	0
114; CHECK: .short	11
115; SmallConstant (0)
116; CHECK: .byte	4
117; CHECK-NEXT:   .byte   0
118; CHECK: .short 8
119; CHECK: .short	0
120; CHECK-NEXT:   .short  0
121; CHECK: .long	0
122; SmallConstant (0)
123; CHECK: .byte	4
124; CHECK-NEXT:   .byte   0
125; CHECK: .short 8
126; CHECK: .short	0
127; CHECK-NEXT:   .short  0
128; CHECK: .long	0
129; SmallConstant (2)
130; CHECK: .byte	4
131; CHECK-NEXT:   .byte   0
132; CHECK: .short 8
133; CHECK: .short	0
134; CHECK-NEXT:   .short  0
135; CHECK: .long	2
136; Indirect Spill Slot [RSP+0]
137; CHECK: .byte	3
138; CHECK-NEXT:   .byte   0
139; CHECK: .short 8
140; CHECK: .short	7
141; CHECK-NEXT:   .short  0
142; CHECK: .long	16
143; SmallConstant  (0)
144; CHECK: .byte	4
145; CHECK-NEXT:   .byte   0
146; CHECK: .short 8
147; CHECK: .short	0
148; CHECK-NEXT:   .short  0
149; CHECK: .long	0
150; SmallConstant  (0)
151; CHECK: .byte	4
152; CHECK-NEXT:   .byte   0
153; CHECK: .short 8
154; CHECK: .short	0
155; CHECK-NEXT:   .short  0
156; CHECK: .long	0
157; SmallConstant  (0)
158; CHECK: .byte	4
159; CHECK-NEXT:   .byte   0
160; CHECK: .short 8
161; CHECK: .short	0
162; CHECK-NEXT:   .short  0
163; CHECK: .long	0
164; Indirect Spill Slot [RSP+16]
165; CHECK: .byte	3
166; CHECK-NEXT:   .byte   0
167; CHECK: .short 8
168; CHECK: .short	7
169; CHECK-NEXT:   .short  0
170; CHECK: .long	16
171; Indirect Spill Slot [RSP+8]
172; CHECK: .byte	3
173; CHECK-NEXT:   .byte   0
174; CHECK: .short 8
175; CHECK: .short	7
176; CHECK-NEXT:   .short  0
177; CHECK: .long	8
178; Indirect Spill Slot [RSP+16]
179; CHECK: .byte	3
180; CHECK-NEXT:   .byte   0
181; CHECK: .short 8
182; CHECK: .short	7
183; CHECK-NEXT:   .short  0
184; CHECK: .long	16
185; Indirect Spill Slot [RSP+16]
186; CHECK: .byte	3
187; CHECK-NEXT:   .byte   0
188; CHECK: .short 8
189; CHECK: .short	7
190; CHECK-NEXT:   .short  0
191; CHECK: .long	16
192
193; No Padding or LiveOuts
194; CHECK: .short	0
195; CHECK: .short	0
196; CHECK: .p2align	3
197
198;
199; test_derived_arg
200
201; Statepoint ID
202; CHECK-NEXT: .quad	0
203
204; Callsites
205; Constant arguments
206; CHECK-NEXT: .long	.Ltmp1-test_derived_arg
207; CHECK: .short	0
208; CHECK: .short	11
209; SmallConstant (0)
210; CHECK: .byte	4
211; CHECK-NEXT:   .byte   0
212; CHECK: .short 8
213; CHECK: .short	0
214; CHECK-NEXT:   .short  0
215; CHECK: .long	0
216; SmallConstant (2)
217; CHECK: .byte	4
218; CHECK-NEXT:   .byte   0
219; CHECK: .short 8
220; CHECK: .short	0
221; CHECK-NEXT:   .short  0
222; CHECK: .long	2
223; Indirect Spill Slot [RSP+0]
224; CHECK: .byte	3
225; CHECK-NEXT:   .byte   0
226; CHECK: .short 8
227; CHECK: .short	7
228; CHECK-NEXT:   .short  0
229; CHECK: .long	16
230; SmallConstant  (0)
231; CHECK: .byte	4
232; CHECK-NEXT:   .byte   0
233; CHECK: .short 8
234; CHECK: .short	0
235; CHECK-NEXT:   .short  0
236; CHECK: .long	0
237; SmallConstant  (0)
238; CHECK: .byte	4
239; CHECK-NEXT:   .byte   0
240; CHECK: .short 8
241; CHECK: .short	0
242; CHECK-NEXT:   .short  0
243; CHECK: .long	0
244; SmallConstant  (0)
245; CHECK: .byte	4
246; CHECK-NEXT:   .byte   0
247; CHECK: .short 8
248; CHECK: .short	0
249; CHECK-NEXT:   .short  0
250; CHECK: .long	0
251; Indirect Spill Slot [RSP+16]
252; CHECK: .byte	3
253; CHECK-NEXT:   .byte   0
254; CHECK: .short 8
255; CHECK: .short	7
256; CHECK-NEXT:   .short  0
257; CHECK: .long	16
258; Indirect Spill Slot [RSP+8]
259; CHECK: .byte	3
260; CHECK-NEXT:   .byte   0
261; CHECK: .short 8
262; CHECK: .short	7
263; CHECK-NEXT:   .short  0
264; CHECK: .long	8
265; Indirect Spill Slot [RSP+16]
266; CHECK: .byte	3
267; CHECK-NEXT:   .byte   0
268; CHECK: .short 8
269; CHECK: .short	7
270; CHECK-NEXT:   .short  0
271; CHECK: .long	16
272; Indirect Spill Slot [RSP+16]
273; CHECK: .byte	3
274; CHECK-NEXT:   .byte   0
275; CHECK: .short 8
276; CHECK: .short	7
277; CHECK-NEXT:   .short  0
278; CHECK: .long	16
279
280; No Padding or LiveOuts
281; CHECK: .short	0
282; CHECK: .short	0
283; CHECK: .p2align	3
284
285; Records for the test_id function:
286
287; The Statepoint ID:
288; CHECK-NEXT: .quad	237
289
290; Instruction Offset
291; CHECK-NEXT: .long	.Ltmp2-test_id
292
293; Reserved:
294; CHECK: .short	0
295
296; NumLocations:
297; CHECK: .short	3
298
299; StkMapRecord[0]:
300; SmallConstant(0):
301; CHECK: .byte	4
302; CHECK-NEXT:   .byte   0
303; CHECK: .short 8
304; CHECK: .short	0
305; CHECK-NEXT:   .short  0
306; CHECK: .long	0
307
308; StkMapRecord[1]:
309; SmallConstant(0):
310; CHECK: .byte	4
311; CHECK-NEXT:   .byte   0
312; CHECK: .short 8
313; CHECK: .short	0
314; CHECK-NEXT:   .short  0
315; CHECK: .long	0
316
317; StkMapRecord[2]:
318; SmallConstant(0):
319; CHECK: .byte	4
320; CHECK-NEXT:   .byte   0
321; CHECK: .short 8
322; CHECK: .short	0
323; CHECK-NEXT:   .short  0
324; CHECK: .long	0
325
326; No padding or LiveOuts
327; CHECK: .short	0
328; CHECK: .short	0
329; CHECK: .p2align	3
330