• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs -O3 -restrict-statepoint-remat < %s | FileCheck %s
3target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
4target triple = "x86_64-apple-macosx10.11.0"
5
6declare void @bar() #0
7declare void @baz()
8
9define void @test1(i32 %a) gc "statepoint-example" {
10; CHECK-LABEL: test1:
11; CHECK:       ## %bb.0: ## %entry
12; CHECK-NEXT:    pushq %rax
13; CHECK-NEXT:    .cfi_def_cfa_offset 16
14; CHECK-NEXT:    callq _bar
15; CHECK-NEXT:  Ltmp0:
16; CHECK-NEXT:    popq %rax
17; CHECK-NEXT:    retq
18entry:
19; We expect the argument to be passed in an extra register to bar
20  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a)]
21  ret void
22}
23
24define void @test2(i32 %a, i32 %b) gc "statepoint-example" {
25; CHECK-LABEL: test2:
26; CHECK:       ## %bb.0: ## %entry
27; CHECK-NEXT:    pushq %rbp
28; CHECK-NEXT:    .cfi_def_cfa_offset 16
29; CHECK-NEXT:    pushq %rbx
30; CHECK-NEXT:    .cfi_def_cfa_offset 24
31; CHECK-NEXT:    pushq %rax
32; CHECK-NEXT:    .cfi_def_cfa_offset 32
33; CHECK-NEXT:    .cfi_offset %rbx, -24
34; CHECK-NEXT:    .cfi_offset %rbp, -16
35; CHECK-NEXT:    movl %esi, %ebx
36; CHECK-NEXT:    movl %edi, %ebp
37; CHECK-NEXT:    callq _bar
38; CHECK-NEXT:  Ltmp1:
39; CHECK-NEXT:    callq _bar
40; CHECK-NEXT:  Ltmp2:
41; CHECK-NEXT:    addq $8, %rsp
42; CHECK-NEXT:    popq %rbx
43; CHECK-NEXT:    popq %rbp
44; CHECK-NEXT:    retq
45entry:
46; Because the first call clobbers esi, we have to move the values into
47; new registers.  Note that they stay in the registers for both calls.
48  call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a, i32 %b)]
49  call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %b, i32 %a)]
50  ret void
51}
52
53define void @test3(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i) gc "statepoint-example" {
54; CHECK-LABEL: test3:
55; CHECK:       ## %bb.0: ## %entry
56; CHECK-NEXT:    pushq %rax
57; CHECK-NEXT:    .cfi_def_cfa_offset 16
58; CHECK-NEXT:    callq _bar
59; CHECK-NEXT:  Ltmp3:
60; CHECK-NEXT:    popq %rax
61; CHECK-NEXT:    retq
62entry:
63; We directly reference the argument slot
64  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i)]
65  ret void
66}
67
68; This case just confirms that we don't crash when given more live values
69; than registers.  This is a case where we *have* to use a stack slot.  This
70; also ends up being a good test of whether we can fold loads from immutable
71; stack slots into the statepoint.
72define void @test4(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" {
73; CHECK-LABEL: test4:
74; CHECK:       ## %bb.0: ## %entry
75; CHECK-NEXT:    pushq %rax
76; CHECK-NEXT:    .cfi_def_cfa_offset 16
77; CHECK-NEXT:    callq _bar
78; CHECK-NEXT:  Ltmp4:
79; CHECK-NEXT:    popq %rax
80; CHECK-NEXT:    retq
81entry:
82  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z)]
83  ret void
84}
85
86; A live-through gc-value must be spilled even if it is also a live-in deopt
87; value.  For live-in, we could technically report the register copy, but from
88; a code quality perspective it's better to reuse the required stack slot so
89; as to put less stress on the register allocator for no benefit.
90define  i32 addrspace(1)* @test5(i32 %a, i32 addrspace(1)* %p) gc "statepoint-example" {
91; CHECK-LABEL: test5:
92; CHECK:       ## %bb.0: ## %entry
93; CHECK-NEXT:    pushq %rax
94; CHECK-NEXT:    .cfi_def_cfa_offset 16
95; CHECK-NEXT:    movq %rsi, (%rsp)
96; CHECK-NEXT:    callq _bar
97; CHECK-NEXT:  Ltmp5:
98; CHECK-NEXT:    movq (%rsp), %rax
99; CHECK-NEXT:    popq %rcx
100; CHECK-NEXT:    retq
101entry:
102  %token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["gc-live"(i32 addrspace(1)* %p), "deopt"(i32 %a)]
103  %p2 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %token,  i32 0, i32 0)
104  ret i32 addrspace(1)* %p2
105}
106
107; Show the interaction of live-through spilling followed by live-in.
108define void @test6(i32 %a) gc "statepoint-example" {
109; CHECK-LABEL: test6:
110; CHECK:       ## %bb.0: ## %entry
111; CHECK-NEXT:    pushq %rbx
112; CHECK-NEXT:    .cfi_def_cfa_offset 16
113; CHECK-NEXT:    subq $16, %rsp
114; CHECK-NEXT:    .cfi_def_cfa_offset 32
115; CHECK-NEXT:    .cfi_offset %rbx, -16
116; CHECK-NEXT:    movl %edi, %ebx
117; CHECK-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
118; CHECK-NEXT:    callq _baz
119; CHECK-NEXT:  Ltmp6:
120; CHECK-NEXT:    callq _bar
121; CHECK-NEXT:  Ltmp7:
122; CHECK-NEXT:    addq $16, %rsp
123; CHECK-NEXT:    popq %rbx
124; CHECK-NEXT:    retq
125entry:
126  call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @baz, i32 0, i32 0, i32 0, i32 0) ["deopt"(i32 %a)]
127  call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a)]
128  ret void
129}
130
131; A variant of test6 where values are not directly foldable from stack slots.
132; This stresses our rematerialization handling.
133define void @test7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" {
134; The code for this is terrible, check simply for correctness for the moment
135; CHECK-LABEL: test7:
136; CHECK:       ## %bb.0: ## %entry
137; CHECK-NEXT:    pushq %rbp
138; CHECK-NEXT:    .cfi_def_cfa_offset 16
139; CHECK-NEXT:    pushq %r15
140; CHECK-NEXT:    .cfi_def_cfa_offset 24
141; CHECK-NEXT:    pushq %r14
142; CHECK-NEXT:    .cfi_def_cfa_offset 32
143; CHECK-NEXT:    pushq %r13
144; CHECK-NEXT:    .cfi_def_cfa_offset 40
145; CHECK-NEXT:    pushq %r12
146; CHECK-NEXT:    .cfi_def_cfa_offset 48
147; CHECK-NEXT:    pushq %rbx
148; CHECK-NEXT:    .cfi_def_cfa_offset 56
149; CHECK-NEXT:    subq $88, %rsp
150; CHECK-NEXT:    .cfi_def_cfa_offset 144
151; CHECK-NEXT:    .cfi_offset %rbx, -56
152; CHECK-NEXT:    .cfi_offset %r12, -48
153; CHECK-NEXT:    .cfi_offset %r13, -40
154; CHECK-NEXT:    .cfi_offset %r14, -32
155; CHECK-NEXT:    .cfi_offset %r15, -24
156; CHECK-NEXT:    .cfi_offset %rbp, -16
157; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
158; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
159; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
160; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
161; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
162; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
163; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
164; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
165; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
166; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
167; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
168; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
169; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
170; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
171; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
172; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
173; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
174; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
175; CHECK-NEXT:    movl %edi, %edi
176; CHECK-NEXT:    movl %esi, %esi
177; CHECK-NEXT:    movl %edx, %edx
178; CHECK-NEXT:    movl %ecx, %ecx
179; CHECK-NEXT:    movl %r8d, %r8d
180; CHECK-NEXT:    movl %r9d, %r9d
181; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
182; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
183; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
184; CHECK-NEXT:    movq %rax, (%rsp) ## 8-byte Spill
185; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebp
186; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r13d
187; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r12d
188; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r15d
189; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r14d
190; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebx
191; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r11d
192; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r10d
193; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
194; CHECK-NEXT:    callq _bar ## 88-byte Folded Reload
195; CHECK-NEXT:  Ltmp8:
196; CHECK-NEXT:    addq $88, %rsp
197; CHECK-NEXT:    popq %rbx
198; CHECK-NEXT:    popq %r12
199; CHECK-NEXT:    popq %r13
200; CHECK-NEXT:    popq %r14
201; CHECK-NEXT:    popq %r15
202; CHECK-NEXT:    popq %rbp
203; CHECK-NEXT:    retq
204entry:
205  %a64 = zext i32 %a to i64
206  %b64 = zext i32 %b to i64
207  %c64 = zext i32 %c to i64
208  %d64 = zext i32 %d to i64
209  %e64 = zext i32 %e to i64
210  %f64 = zext i32 %f to i64
211  %g64 = zext i32 %g to i64
212  %h64 = zext i32 %h to i64
213  %i64 = zext i32 %i to i64
214  %j64 = zext i32 %j to i64
215  %k64 = zext i32 %k to i64
216  %l64 = zext i32 %l to i64
217  %m64 = zext i32 %m to i64
218  %n64 = zext i32 %n to i64
219  %o64 = zext i32 %o to i64
220  %p64 = zext i32 %p to i64
221  %q64 = zext i32 %q to i64
222  %r64 = zext i32 %r to i64
223  %s64 = zext i32 %s to i64
224  %t64 = zext i32 %t to i64
225  %u64 = zext i32 %u to i64
226  %v64 = zext i32 %v to i64
227  %w64 = zext i32 %w to i64
228  %x64 = zext i32 %x to i64
229  %y64 = zext i32 %y to i64
230  %z64 = zext i32 %z to i64
231  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i64 %a64, i64 %b64, i64 %c64, i64 %d64, i64 %e64, i64 %f64, i64 %g64, i64 %h64, i64 %i64, i64 %j64, i64 %k64, i64 %l64, i64 %m64, i64 %n64, i64 %o64, i64 %p64, i64 %q64, i64 %r64, i64 %s64, i64 %t64, i64 %u64, i64 %v64, i64 %w64, i64 %x64, i64 %y64, i64 %z64)]
232  ret void
233}
234
235; a variant of test7 with mixed types chosen to exercise register aliases
236define void @test8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" {
237; The code for this is terrible, check simply for correctness for the moment
238; CHECK-LABEL: test8:
239; CHECK:       ## %bb.0: ## %entry
240; CHECK-NEXT:    pushq %rbp
241; CHECK-NEXT:    .cfi_def_cfa_offset 16
242; CHECK-NEXT:    pushq %r15
243; CHECK-NEXT:    .cfi_def_cfa_offset 24
244; CHECK-NEXT:    pushq %r14
245; CHECK-NEXT:    .cfi_def_cfa_offset 32
246; CHECK-NEXT:    pushq %r13
247; CHECK-NEXT:    .cfi_def_cfa_offset 40
248; CHECK-NEXT:    pushq %r12
249; CHECK-NEXT:    .cfi_def_cfa_offset 48
250; CHECK-NEXT:    pushq %rbx
251; CHECK-NEXT:    .cfi_def_cfa_offset 56
252; CHECK-NEXT:    subq $72, %rsp
253; CHECK-NEXT:    .cfi_def_cfa_offset 128
254; CHECK-NEXT:    .cfi_offset %rbx, -56
255; CHECK-NEXT:    .cfi_offset %r12, -48
256; CHECK-NEXT:    .cfi_offset %r13, -40
257; CHECK-NEXT:    .cfi_offset %r14, -32
258; CHECK-NEXT:    .cfi_offset %r15, -24
259; CHECK-NEXT:    .cfi_offset %rbp, -16
260; CHECK-NEXT:    movl %r9d, %r10d
261; CHECK-NEXT:    movl %r8d, %r9d
262; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
263; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
264; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
265; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
266; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
267; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
268; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
269; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
270; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
271; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
272; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
273; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
274; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
275; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
276; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
277; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
278; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
279; CHECK-NEXT:    movq %rax, (%rsp) ## 8-byte Spill
280; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebp
281; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r13d
282; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r12d
283; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r15d
284; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r14d
285; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %ebx
286; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r11d
287; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %r8d
288; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
289; CHECK-NEXT:    callq _bar ## 72-byte Folded Reload
290; CHECK-NEXT:  Ltmp9:
291; CHECK-NEXT:    addq $72, %rsp
292; CHECK-NEXT:    popq %rbx
293; CHECK-NEXT:    popq %r12
294; CHECK-NEXT:    popq %r13
295; CHECK-NEXT:    popq %r14
296; CHECK-NEXT:    popq %r15
297; CHECK-NEXT:    popq %rbp
298; CHECK-NEXT:    retq
299entry:
300  %a8 = trunc i32 %a to i8
301  %b8 = trunc i32 %b to i8
302  %c8 = trunc i32 %c to i8
303  %d8 = trunc i32 %d to i8
304  %e16 = trunc i32 %e to i16
305  %f16 = trunc i32 %f to i16
306  %g16 = trunc i32 %g to i16
307  %h16 = trunc i32 %h to i16
308  %i64 = zext i32 %i to i64
309  %j64 = zext i32 %j to i64
310  %k64 = zext i32 %k to i64
311  %l64 = zext i32 %l to i64
312  %m64 = zext i32 %m to i64
313  %n64 = zext i32 %n to i64
314  %o64 = zext i32 %o to i64
315  %p64 = zext i32 %p to i64
316  %q64 = zext i32 %q to i64
317  %r64 = zext i32 %r to i64
318  %s64 = zext i32 %s to i64
319  %t64 = zext i32 %t to i64
320  %u64 = zext i32 %u to i64
321  %v64 = zext i32 %v to i64
322  %w64 = zext i32 %w to i64
323  %x64 = zext i32 %x to i64
324  %y64 = zext i32 %y to i64
325  %z64 = zext i32 %z to i64
326  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i8 %a8, i8 %b8, i8 %c8, i8 %d8, i16 %e16, i16 %f16, i16 %g16, i16 %h16, i64 %i64, i64 %j64, i64 %k64, i64 %l64, i64 %m64, i64 %n64, i64 %o64, i64 %p64, i64 %q64, i64 %r64, i64 %s64, i64 %t64, i64 %u64, i64 %v64, i64 %w64, i64 %x64, i64 %y64, i64 %z64)]
327  ret void
328}
329
330; Test perfect forwarding of argument registers and stack slots to the
331; deopt bundle uses
332define void @test9(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" {
333; CHECK-LABEL: test9:
334; CHECK:       ## %bb.0: ## %entry
335; CHECK-NEXT:    pushq %rax
336; CHECK-NEXT:    .cfi_def_cfa_offset 16
337; CHECK-NEXT:    callq _bar
338; CHECK-NEXT:  Ltmp10:
339; CHECK-NEXT:    popq %rax
340; CHECK-NEXT:    retq
341
342entry:
343  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z)]
344  ret void
345}
346
347; Test enough folding of argument slots when we have one call which clobbers
348; registers before a second which needs them - i.e. we must do something with
349; arguments originally passed in registers
350define void @test10(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" {
351; FIXME (minor): It would be better to just spill (and fold reload) for
352; argument registers then spill and fill all the CSRs.
353; CHECK-LABEL: test10:
354; CHECK:       ## %bb.0: ## %entry
355; CHECK-NEXT:    pushq %rbp
356; CHECK-NEXT:    .cfi_def_cfa_offset 16
357; CHECK-NEXT:    pushq %r15
358; CHECK-NEXT:    .cfi_def_cfa_offset 24
359; CHECK-NEXT:    pushq %r14
360; CHECK-NEXT:    .cfi_def_cfa_offset 32
361; CHECK-NEXT:    pushq %r13
362; CHECK-NEXT:    .cfi_def_cfa_offset 40
363; CHECK-NEXT:    pushq %r12
364; CHECK-NEXT:    .cfi_def_cfa_offset 48
365; CHECK-NEXT:    pushq %rbx
366; CHECK-NEXT:    .cfi_def_cfa_offset 56
367; CHECK-NEXT:    pushq %rax
368; CHECK-NEXT:    .cfi_def_cfa_offset 64
369; CHECK-NEXT:    .cfi_offset %rbx, -56
370; CHECK-NEXT:    .cfi_offset %r12, -48
371; CHECK-NEXT:    .cfi_offset %r13, -40
372; CHECK-NEXT:    .cfi_offset %r14, -32
373; CHECK-NEXT:    .cfi_offset %r15, -24
374; CHECK-NEXT:    .cfi_offset %rbp, -16
375; CHECK-NEXT:    movl %r9d, %r15d
376; CHECK-NEXT:    movl %r8d, %r14d
377; CHECK-NEXT:    movl %ecx, %r12d
378; CHECK-NEXT:    movl %edx, %r13d
379; CHECK-NEXT:    movl %esi, %ebx
380; CHECK-NEXT:    movl %edi, %ebp
381; CHECK-NEXT:    callq _bar
382; CHECK-NEXT:  Ltmp11:
383; CHECK-NEXT:    callq _bar
384; CHECK-NEXT:  Ltmp12:
385; CHECK-NEXT:    addq $8, %rsp
386; CHECK-NEXT:    popq %rbx
387; CHECK-NEXT:    popq %r12
388; CHECK-NEXT:    popq %r13
389; CHECK-NEXT:    popq %r14
390; CHECK-NEXT:    popq %r15
391; CHECK-NEXT:    popq %rbp
392; CHECK-NEXT:    retq
393
394entry:
395  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z)]
396  %statepoint_token2 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z)]
397  ret void
398}
399
400; Check that we can remat some uses of a def despite not remating before the
401; statepoint user.
402define i64 @test11(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" {
403; FIXME: The codegen for this is correct, but horrible.  Lots of room for
404; improvement if we so desire.
405; CHECK-LABEL: test11:
406; CHECK:       ## %bb.0: ## %entry
407; CHECK-NEXT:    pushq %rbp
408; CHECK-NEXT:    .cfi_def_cfa_offset 16
409; CHECK-NEXT:    pushq %r15
410; CHECK-NEXT:    .cfi_def_cfa_offset 24
411; CHECK-NEXT:    pushq %r14
412; CHECK-NEXT:    .cfi_def_cfa_offset 32
413; CHECK-NEXT:    pushq %r13
414; CHECK-NEXT:    .cfi_def_cfa_offset 40
415; CHECK-NEXT:    pushq %r12
416; CHECK-NEXT:    .cfi_def_cfa_offset 48
417; CHECK-NEXT:    pushq %rbx
418; CHECK-NEXT:    .cfi_def_cfa_offset 56
419; CHECK-NEXT:    subq $168, %rsp
420; CHECK-NEXT:    .cfi_def_cfa_offset 224
421; CHECK-NEXT:    .cfi_offset %rbx, -56
422; CHECK-NEXT:    .cfi_offset %r12, -48
423; CHECK-NEXT:    .cfi_offset %r13, -40
424; CHECK-NEXT:    .cfi_offset %r14, -32
425; CHECK-NEXT:    .cfi_offset %r15, -24
426; CHECK-NEXT:    .cfi_offset %rbp, -16
427; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
428; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
429; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
430; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
431; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
432; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
433; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
434; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
435; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
436; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
437; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
438; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
439; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
440; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
441; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
442; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
443; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
444; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
445; CHECK-NEXT:    movl %edi, %ebx
446; CHECK-NEXT:    movl %esi, %r15d
447; CHECK-NEXT:    movl %edx, %r12d
448; CHECK-NEXT:    movl %ecx, %r13d
449; CHECK-NEXT:    movl %r8d, %ebp
450; CHECK-NEXT:    movl %r9d, %r14d
451; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
452; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
453; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
454; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
455; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
456; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
457; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
458; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
459; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
460; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
461; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
462; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
463; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
464; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
465; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
466; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
467; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
468; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
469; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
470; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
471; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
472; CHECK-NEXT:    movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
473; CHECK-NEXT:    callq _bar ## 160-byte Folded Reload
474; CHECK-NEXT:  Ltmp13:
475; CHECK-NEXT:    addq %r15, %rbx
476; CHECK-NEXT:    addq %r12, %rbx
477; CHECK-NEXT:    addq %r13, %rbx
478; CHECK-NEXT:    addq %rbp, %rbx
479; CHECK-NEXT:    addq %r14, %rbx
480; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
481; CHECK-NEXT:    addq %rax, %rbx
482; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
483; CHECK-NEXT:    addq %rax, %rbx
484; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
485; CHECK-NEXT:    addq %rax, %rbx
486; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
487; CHECK-NEXT:    addq %rax, %rbx
488; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
489; CHECK-NEXT:    addq %rax, %rbx
490; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
491; CHECK-NEXT:    addq %rax, %rbx
492; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
493; CHECK-NEXT:    addq %rax, %rbx
494; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
495; CHECK-NEXT:    addq %rax, %rbx
496; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
497; CHECK-NEXT:    addq %rax, %rbx
498; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
499; CHECK-NEXT:    addq %rax, %rbx
500; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
501; CHECK-NEXT:    addq %rax, %rbx
502; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
503; CHECK-NEXT:    addq %rax, %rbx
504; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
505; CHECK-NEXT:    addq %rax, %rbx
506; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
507; CHECK-NEXT:    addq %rax, %rbx
508; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
509; CHECK-NEXT:    addq %rax, %rbx
510; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
511; CHECK-NEXT:    addq %rax, %rbx
512; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
513; CHECK-NEXT:    addq %rax, %rbx
514; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
515; CHECK-NEXT:    addq %rax, %rbx
516; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
517; CHECK-NEXT:    addq %rax, %rbx
518; CHECK-NEXT:    movl {{[0-9]+}}(%rsp), %eax
519; CHECK-NEXT:    addq %rax, %rbx
520; CHECK-NEXT:    movq %rbx, %rax
521; CHECK-NEXT:    addq $168, %rsp
522; CHECK-NEXT:    popq %rbx
523; CHECK-NEXT:    popq %r12
524; CHECK-NEXT:    popq %r13
525; CHECK-NEXT:    popq %r14
526; CHECK-NEXT:    popq %r15
527; CHECK-NEXT:    popq %rbp
528; CHECK-NEXT:    retq
529
530entry:
531  %a64 = zext i32 %a to i64
532  %b64 = zext i32 %b to i64
533  %c64 = zext i32 %c to i64
534  %d64 = zext i32 %d to i64
535  %e64 = zext i32 %e to i64
536  %f64 = zext i32 %f to i64
537  %g64 = zext i32 %g to i64
538  %h64 = zext i32 %h to i64
539  %i64 = zext i32 %i to i64
540  %j64 = zext i32 %j to i64
541  %k64 = zext i32 %k to i64
542  %l64 = zext i32 %l to i64
543  %m64 = zext i32 %m to i64
544  %n64 = zext i32 %n to i64
545  %o64 = zext i32 %o to i64
546  %p64 = zext i32 %p to i64
547  %q64 = zext i32 %q to i64
548  %r64 = zext i32 %r to i64
549  %s64 = zext i32 %s to i64
550  %t64 = zext i32 %t to i64
551  %u64 = zext i32 %u to i64
552  %v64 = zext i32 %v to i64
553  %w64 = zext i32 %w to i64
554  %x64 = zext i32 %x to i64
555  %y64 = zext i32 %y to i64
556  %z64 = zext i32 %z to i64
557  call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i64 0, i64 0) ["deopt"(i64 %a64, i64 %b64, i64 %c64, i64 %d64, i64 %e64, i64 %f64, i64 %g64, i64 %h64, i64 %i64, i64 %j64, i64 %k64, i64 %l64, i64 %m64, i64 %n64, i64 %o64, i64 %p64, i64 %q64, i64 %r64, i64 %s64, i64 %t64, i64 %u64, i64 %v64, i64 %w64, i64 %x64, i64 %y64, i64 %z64)]
558  %addab = add i64 %a64, %b64
559  %addc = add i64 %addab, %c64
560  %addd = add i64 %addc, %d64
561  %adde = add i64 %addd, %e64
562  %addf = add i64 %adde, %f64
563  %addg = add i64 %addf, %g64
564  %addh = add i64 %addg, %h64
565  %addi = add i64 %addh, %i64
566  %addj = add i64 %addi, %j64
567  %addk = add i64 %addj, %k64
568  %addl = add i64 %addk, %l64
569  %addm = add i64 %addl, %m64
570  %addn = add i64 %addm, %n64
571  %addo = add i64 %addn, %o64
572  %addp = add i64 %addo, %p64
573  %addq = add i64 %addp, %q64
574  %addr = add i64 %addq, %r64
575  %adds = add i64 %addr, %s64
576  %addt = add i64 %adds, %t64
577  %addu = add i64 %addt, %u64
578  %addv = add i64 %addu, %v64
579  %addw = add i64 %addv, %w64
580  %addx = add i64 %addw, %x64
581  %addy = add i64 %addx, %y64
582  %addz = add i64 %addy, %z64
583  ret i64 %addz
584}
585
586; Demonstrate address of a function (w/o spilling)
587define void @addr_func() gc "statepoint-example" {
588; CHECK-LABEL: addr_func:
589; CHECK:       ## %bb.0: ## %entry
590; CHECK-NEXT:    pushq %rax
591; CHECK-NEXT:    .cfi_def_cfa_offset 16
592; CHECK-NEXT:    movq _bar@{{.*}}(%rip), %rax
593; CHECK-NEXT:    callq _bar
594; CHECK-NEXT:  Ltmp14:
595; CHECK-NEXT:    popq %rax
596; CHECK-NEXT:    retq
597entry:
598  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i64 0, i64 0) ["deopt"(void ()* @bar, void ()* @bar, void ()* @bar)]
599  ret void
600}
601
602; Demonstrate address of a global (w/o spilling)
603@G = external global i32
604define void @addr_global() gc "statepoint-example" {
605; CHECK-LABEL: addr_global:
606; CHECK:       ## %bb.0: ## %entry
607; CHECK-NEXT:    pushq %rax
608; CHECK-NEXT:    .cfi_def_cfa_offset 16
609; CHECK-NEXT:    movq _G@{{.*}}(%rip), %rax
610; CHECK-NEXT:    callq _bar
611; CHECK-NEXT:  Ltmp15:
612; CHECK-NEXT:    popq %rax
613; CHECK-NEXT:    retq
614entry:
615  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i64 0, i64 0) ["deopt"(i32* @G, i32* @G, i32* @G)]
616  ret void
617}
618
619define void @addr_alloca(i32 %v) gc "statepoint-example" {
620; CHECK-LABEL: addr_alloca:
621; CHECK:       ## %bb.0: ## %entry
622; CHECK-NEXT:    pushq %rax
623; CHECK-NEXT:    .cfi_def_cfa_offset 16
624; CHECK-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
625; CHECK-NEXT:    callq _bar
626; CHECK-NEXT:  Ltmp16:
627; CHECK-NEXT:    popq %rax
628; CHECK-NEXT:    retq
629entry:
630  %a = alloca i32
631  store i32 %v, i32* %a
632  %statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 2, i64 0, i64 0) ["deopt"(i32* %a, i32* %a, i32* %a)]
633  ret void
634}
635
636
637; CHECK: Ltmp0-_test1
638; CHECK:      .byte	1
639; CHECK-NEXT:   .byte   0
640; CHECK-NEXT: .short 4
641; CHECK-NEXT: .short	5
642; CHECK-NEXT:   .short  0
643; CHECK-NEXT: .long	0
644
645; CHECK: Ltmp1-_test2
646; CHECK:      .byte	1
647; CHECK-NEXT:   .byte   0
648; CHECK-NEXT: .short 4
649; CHECK-NEXT: .short	6
650; CHECK-NEXT:   .short  0
651; CHECK-NEXT: .long	0
652; CHECK:      .byte	1
653; CHECK-NEXT:   .byte   0
654; CHECK-NEXT: .short 4
655; CHECK-NEXT: .short	3
656; CHECK-NEXT:   .short  0
657; CHECK-NEXT: .long	0
658; CHECK: Ltmp2-_test2
659; CHECK:      .byte	1
660; CHECK-NEXT:   .byte   0
661; CHECK-NEXT: .short 4
662; CHECK-NEXT: .short	3
663; CHECK-NEXT:   .short  0
664; CHECK-NEXT: .long	0
665; CHECK:      .byte	1
666; CHECK-NEXT:   .byte   0
667; CHECK-NEXT: .short 4
668; CHECK-NEXT: .short	6
669; CHECK-NEXT:   .short  0
670; CHECK-NEXT: .long	0
671
672declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
673declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
674
675attributes #0 = { "deopt-lowering"="live-in" }
676attributes #1 = { "deopt-lowering"="live-through" }
677