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
3 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-apple-macosx10.11.0"
9 define void @test1(i32 %a) gc "statepoint-example" {
11 ; CHECK: ## %bb.0: ## %entry
12 ; CHECK-NEXT: pushq %rax
13 ; CHECK-NEXT: .cfi_def_cfa_offset 16
14 ; CHECK-NEXT: callq _bar
16 ; CHECK-NEXT: popq %rax
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 1, i32 %a)
24 define void @test2(i32 %a, i32 %b) gc "statepoint-example" {
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
39 ; CHECK-NEXT: callq _bar
41 ; CHECK-NEXT: addq $8, %rsp
42 ; CHECK-NEXT: popq %rbx
43 ; CHECK-NEXT: popq %rbp
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 2, 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 2, i32 %b, i32 %a)
53 define void @test3(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i) gc "statepoint-example" {
55 ; CHECK: ## %bb.0: ## %entry
56 ; CHECK-NEXT: pushq %rax
57 ; CHECK-NEXT: .cfi_def_cfa_offset 16
58 ; CHECK-NEXT: callq _bar
60 ; CHECK-NEXT: popq %rax
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 9, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i)
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.
72 define 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" {
74 ; CHECK: ## %bb.0: ## %entry
75 ; CHECK-NEXT: pushq %rax
76 ; CHECK-NEXT: .cfi_def_cfa_offset 16
77 ; CHECK-NEXT: callq _bar
79 ; CHECK-NEXT: popq %rax
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 26, 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)
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.
90 define i32 addrspace(1)* @test5(i32 %a, i32 addrspace(1)* %p) gc "statepoint-example" {
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
98 ; CHECK-NEXT: movq (%rsp), %rax
99 ; CHECK-NEXT: popq %rcx
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 1, i32 %a, i32 addrspace(1)* %p, i32 addrspace(1)* %p)
103 %p2 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %token, i32 9, i32 9)
104 ret i32 addrspace(1)* %p2
107 ; Show the interaction of live-through spilling followed by live-in.
108 define 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
120 ; CHECK-NEXT: callq _bar
122 ; CHECK-NEXT: addq $16, %rsp
123 ; CHECK-NEXT: popq %rbx
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 1, 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 1, i32 %a)
131 ; A variant of test6 where values are not directly foldable from stack slots.
132 ; This stresses our rematerialization handling.
133 define 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
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
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 26, 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)
235 ; a variant of test7 with mixed types chosen to exercise register aliases
236 define 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
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
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 26, 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)
330 ; Test perfect forwarding of argument registers and stack slots to the
332 define 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
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 26, 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)
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
350 define 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
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 26, 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 26, 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)
400 ; Check that we can remat some uses of a def despite not remating before the
402 define 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
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 26, 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
586 ; Demonstrate address of a function (w/o spilling)
587 define 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
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 3, void ()* @bar, void ()* @bar, void ()* @bar)
602 ; Demonstrate address of a global (w/o spilling)
603 @G = external global i32
604 define 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
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 3, i32* @G, i32* @G, i32* @G)
619 define 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
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 3, i32* %a, i32* %a, i32* %a)
637 ; CHECK: Ltmp0-_test1
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
645 ; CHECK: Ltmp1-_test2
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
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
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
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
672 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
673 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
675 attributes #0 = { "deopt-lowering"="live-in" }
676 attributes #1 = { "deopt-lowering"="live-through" }