1; RUN: llc < %s -stack-symbol-ordering=0 -mtriple="x86_64-pc-linux-gnu" | FileCheck %s
2; RUN: llc < %s -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 1
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 test_derived_arg
96; CHECK-NEXT:   .quad 40
97; CHECK-NEXT:   .quad test_id
98; CHECK-NEXT:   .quad 8
99
100;
101; test
102;
103
104; Statepoint ID
105; CHECK-NEXT: .quad	0
106
107; Callsites
108; Constant arguments
109; CHECK-NEXT: .long	.Ltmp1-test
110; CHECK: .short	0
111; CHECK: .short	11
112; SmallConstant (0)
113; CHECK: .byte	4
114; CHECK: .byte	8
115; CHECK: .short	0
116; CHECK: .long	0
117; SmallConstant (0)
118; CHECK: .byte	4
119; CHECK: .byte	8
120; CHECK: .short	0
121; CHECK: .long	0
122; SmallConstant (2)
123; CHECK: .byte	4
124; CHECK: .byte	8
125; CHECK: .short	0
126; CHECK: .long	2
127; Indirect Spill Slot [RSP+0]
128; CHECK: .byte	3
129; CHECK: .byte	8
130; CHECK: .short	7
131; CHECK: .long	16
132; SmallConstant  (0)
133; CHECK: .byte	4
134; CHECK: .byte	8
135; CHECK: .short	0
136; CHECK: .long	0
137; SmallConstant  (0)
138; CHECK: .byte	4
139; CHECK: .byte	8
140; CHECK: .short	0
141; CHECK: .long	0
142; SmallConstant  (0)
143; CHECK: .byte	4
144; CHECK: .byte	8
145; CHECK: .short	0
146; CHECK: .long	0
147; Indirect Spill Slot [RSP+16]
148; CHECK: .byte	3
149; CHECK: .byte	8
150; CHECK: .short	7
151; CHECK: .long	16
152; Indirect Spill Slot [RSP+8]
153; CHECK: .byte	3
154; CHECK: .byte	8
155; CHECK: .short	7
156; CHECK: .long	8
157; Indirect Spill Slot [RSP+16]
158; CHECK: .byte	3
159; CHECK: .byte	8
160; CHECK: .short	7
161; CHECK: .long	16
162; Indirect Spill Slot [RSP+16]
163; CHECK: .byte	3
164; CHECK: .byte	8
165; CHECK: .short	7
166; CHECK: .long	16
167
168; No Padding or LiveOuts
169; CHECK: .short	0
170; CHECK: .short	0
171; CHECK: .p2align	3
172
173;
174; test_derived_arg
175
176; Statepoint ID
177; CHECK-NEXT: .quad	0
178
179; Callsites
180; Constant arguments
181; CHECK-NEXT: .long	.Ltmp3-test_derived_arg
182; CHECK: .short	0
183; CHECK: .short	11
184; SmallConstant (0)
185; CHECK: .byte	4
186; CHECK: .byte	8
187; CHECK: .short	0
188; CHECK: .long	0
189; SmallConstant (2)
190; CHECK: .byte	4
191; CHECK: .byte	8
192; CHECK: .short	0
193; CHECK: .long	2
194; Indirect Spill Slot [RSP+0]
195; CHECK: .byte	3
196; CHECK: .byte	8
197; CHECK: .short	7
198; CHECK: .long	16
199; SmallConstant  (0)
200; CHECK: .byte	4
201; CHECK: .byte	8
202; CHECK: .short	0
203; CHECK: .long	0
204; SmallConstant  (0)
205; CHECK: .byte	4
206; CHECK: .byte	8
207; CHECK: .short	0
208; CHECK: .long	0
209; SmallConstant  (0)
210; CHECK: .byte	4
211; CHECK: .byte	8
212; CHECK: .short	0
213; CHECK: .long	0
214; Indirect Spill Slot [RSP+16]
215; CHECK: .byte	3
216; CHECK: .byte	8
217; CHECK: .short	7
218; CHECK: .long	16
219; Indirect Spill Slot [RSP+8]
220; CHECK: .byte	3
221; CHECK: .byte	8
222; CHECK: .short	7
223; CHECK: .long	8
224; Indirect Spill Slot [RSP+16]
225; CHECK: .byte	3
226; CHECK: .byte	8
227; CHECK: .short	7
228; CHECK: .long	16
229; Indirect Spill Slot [RSP+16]
230; CHECK: .byte	3
231; CHECK: .byte	8
232; CHECK: .short	7
233; CHECK: .long	16
234
235; No Padding or LiveOuts
236; CHECK: .short	0
237; CHECK: .short	0
238; CHECK: .p2align	3
239
240; Records for the test_id function:
241
242; The Statepoint ID:
243; CHECK-NEXT: .quad	237
244
245; Instruction Offset
246; CHECK-NEXT: .long	.Ltmp5-test_id
247
248; Reserved:
249; CHECK: .short	0
250
251; NumLocations:
252; CHECK: .short	3
253
254; StkMapRecord[0]:
255; SmallConstant(0):
256; CHECK: .byte	4
257; CHECK: .byte	8
258; CHECK: .short	0
259; CHECK: .long	0
260
261; StkMapRecord[1]:
262; SmallConstant(0):
263; CHECK: .byte	4
264; CHECK: .byte	8
265; CHECK: .short	0
266; CHECK: .long	0
267
268; StkMapRecord[2]:
269; SmallConstant(0):
270; CHECK: .byte	4
271; CHECK: .byte	8
272; CHECK: .short	0
273; CHECK: .long	0
274
275; No padding or LiveOuts
276; CHECK: .short	0
277; CHECK: .short	0
278; CHECK: .p2align	3
279
280