1; RUN: llc < %s | FileCheck %s
2; This test is a sanity check to ensure statepoints are generating StackMap
3; sections correctly.  This is not intended to be a rigorous test of the
4; StackMap format (see the stackmap tests for that).
5
6target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
7target triple = "x86_64-pc-linux-gnu"
8
9declare zeroext i1 @return_i1()
10
11define i1 @test(i32 addrspace(1)* %ptr_base, i32 %arg)
12  gc "statepoint-example" {
13; CHECK-LABEL: test
14; Do we see two spills for the local values and the store to the
15; alloca?
16; CHECK: subq	$40, %rsp
17; CHECK: movq	$0,   24(%rsp)
18; CHECK: movq	%rdi, 16(%rsp)
19; CHECK: movq	%rax, 8(%rsp)
20; CHECK: callq return_i1
21; CHECK: addq	$40, %rsp
22; CHECK: retq
23entry:
24  %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
25  store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
26  %ptr_derived = getelementptr i32, i32 addrspace(1)* %ptr_base, i32 %arg
27  %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)
28  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
29  %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
30  %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 10)
31  %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 11, i32 11)
32;
33  ret i1 %call1
34}
35
36; This is similar to the previous test except that we have derived pointer as
37; argument to the function. Despite that this can not happen after the
38; RewriteSafepointForGC pass, lowering should be able to handle it anyway.
39define i1 @test_derived_arg(i32 addrspace(1)* %ptr_base,
40                            i32 addrspace(1)* %ptr_derived)
41  gc "statepoint-example" {
42; CHECK-LABEL: test_derived_arg
43; Do we see two spills for the local values and the store to the
44; alloca?
45; CHECK: subq	$40, %rsp
46; CHECK: movq	$0,   24(%rsp)
47; CHECK: movq	%rdi, 16(%rsp)
48; CHECK: movq	%rsi, 8(%rsp)
49; CHECK: callq return_i1
50; CHECK: addq	$40, %rsp
51; CHECK: retq
52entry:
53  %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
54  store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
55  %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)
56  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
57  %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9)
58  %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 10)
59  %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 11, i32 11)
60;
61  ret i1 %call1
62}
63
64; Simple test case to check that we emit the ID field correctly
65define i1 @test_id() gc "statepoint-example" {
66; CHECK-LABEL: test_id
67entry:
68  %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)
69  %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
70  ret i1 %call1
71}
72
73
74declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
75declare i1 @llvm.experimental.gc.result.i1(i32)
76declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
77
78; CHECK-LABEL: .section .llvm_stackmaps
79; CHECK-NEXT:  __LLVM_StackMaps:
80; Header
81; CHECK-NEXT:   .byte 1
82; CHECK-NEXT:   .byte 0
83; CHECK-NEXT:   .short 0
84; Num Functions
85; CHECK-NEXT:   .long 3
86; Num LargeConstants
87; CHECK-NEXT:   .long 0
88; Num Callsites
89; CHECK-NEXT:   .long 3
90
91; Functions and stack size
92; CHECK-NEXT:   .quad test
93; CHECK-NEXT:   .quad 40
94; CHECK-NEXT:   .quad test_derived_arg
95; CHECK-NEXT:   .quad 40
96
97;
98; test
99;
100
101; Large Constants
102; Statepoint ID only
103; CHECK: .quad	0
104
105; Callsites
106; Constant arguments
107; CHECK: .long	.Ltmp1-test
108; CHECK: .short	0
109; CHECK: .short	11
110; SmallConstant (0)
111; CHECK: .byte	4
112; CHECK: .byte	8
113; CHECK: .short	0
114; CHECK: .long	0
115; SmallConstant (0)
116; CHECK: .byte	4
117; CHECK: .byte	8
118; CHECK: .short	0
119; CHECK: .long	0
120; SmallConstant (2)
121; CHECK: .byte	4
122; CHECK: .byte	8
123; CHECK: .short	0
124; CHECK: .long	2
125; Direct Spill Slot [RSP+0]
126; CHECK: .byte	2
127; CHECK: .byte	8
128; CHECK: .short	7
129; CHECK: .long	16
130; SmallConstant  (0)
131; CHECK: .byte	4
132; CHECK: .byte	8
133; CHECK: .short	0
134; CHECK: .long	0
135; SmallConstant  (0)
136; CHECK: .byte	4
137; CHECK: .byte	8
138; CHECK: .short	0
139; CHECK: .long	0
140; SmallConstant  (0)
141; CHECK: .byte	4
142; CHECK: .byte	8
143; CHECK: .short	0
144; CHECK: .long	0
145; Direct Spill Slot [RSP+16]
146; CHECK: .byte	2
147; CHECK: .byte	8
148; CHECK: .short	7
149; CHECK: .long	16
150; Direct Spill Slot [RSP+8]
151; CHECK: .byte	2
152; CHECK: .byte	8
153; CHECK: .short	7
154; CHECK: .long	8
155; Direct Spill Slot [RSP+16]
156; CHECK: .byte	2
157; CHECK: .byte	8
158; CHECK: .short	7
159; CHECK: .long	16
160; Direct Spill Slot [RSP+16]
161; CHECK: .byte	2
162; CHECK: .byte	8
163; CHECK: .short	7
164; CHECK: .long	16
165
166; No Padding or LiveOuts
167; CHECK: .short	0
168; CHECK: .short	0
169; CHECK: .align	8
170
171;
172; test_derived_arg
173;
174
175; Large Constants
176; Statepoint ID only
177; CHECK: .quad	0
178
179; Callsites
180; Constant arguments
181; CHECK: .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; Direct Spill Slot [RSP+0]
195; CHECK: .byte	2
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; Direct Spill Slot [RSP+16]
215; CHECK: .byte	2
216; CHECK: .byte	8
217; CHECK: .short	7
218; CHECK: .long	16
219; Direct Spill Slot [RSP+8]
220; CHECK: .byte	2
221; CHECK: .byte	8
222; CHECK: .short	7
223; CHECK: .long	8
224; Direct Spill Slot [RSP+16]
225; CHECK: .byte	2
226; CHECK: .byte	8
227; CHECK: .short	7
228; CHECK: .long	16
229; Direct Spill Slot [RSP+16]
230; CHECK: .byte	2
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: .align	8
239
240; Records for the test_id function:
241; No large constants
242
243; The Statepoint ID:
244; CHECK: .quad	237
245
246; Instruction Offset
247; CHECK: .long	.Ltmp5-test_id
248
249; Reserved:
250; CHECK: .short	0
251
252; NumLocations:
253; CHECK: .short	3
254
255; StkMapRecord[0]:
256; SmallConstant(0):
257; CHECK: .byte	4
258; CHECK: .byte	8
259; CHECK: .short	0
260; CHECK: .long	0
261
262; StkMapRecord[1]:
263; SmallConstant(0):
264; CHECK: .byte	4
265; CHECK: .byte	8
266; CHECK: .short	0
267; CHECK: .long	0
268
269; StkMapRecord[2]:
270; SmallConstant(0):
271; CHECK: .byte	4
272; CHECK: .byte	8
273; CHECK: .short	0
274; CHECK: .long	0
275
276; No padding or LiveOuts
277; CHECK: .short	0
278; CHECK: .short	0
279; CHECK: .align	8
280
281