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