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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(i32 %a, i32 %b)]
49 call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(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)]
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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(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)]
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 ptr addrspace(1) @test5(i32 %a, ptr 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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i32 0, i32 0) ["gc-live"(ptr addrspace(1) %p), "deopt"(i32 %a)]
103 %p2 = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %token, i32 0, i32 0)
104 ret ptr 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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @baz, i32 0, i32 0, i32 0, i32 0) ["deopt"(i32 %a)]
127 call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i32 0, i32 0) ["deopt"(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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(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)]
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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(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)]
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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(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)]
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, %ebp
376 ; CHECK-NEXT: movl %r8d, %ebx
377 ; CHECK-NEXT: movl %ecx, %r14d
378 ; CHECK-NEXT: movl %edx, %r15d
379 ; CHECK-NEXT: movl %esi, %r12d
380 ; CHECK-NEXT: movl %edi, %r13d
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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(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, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(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)]
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, %eax
446 ; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
447 ; CHECK-NEXT: movl %esi, %eax
448 ; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
449 ; CHECK-NEXT: movl %edx, %r14d
450 ; CHECK-NEXT: movl %ecx, %eax
451 ; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
452 ; CHECK-NEXT: movl %r8d, %r15d
453 ; CHECK-NEXT: movl %r9d, %eax
454 ; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
455 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r13d
456 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
457 ; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
458 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
459 ; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
460 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
461 ; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
462 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebp
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), %r12d
468 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
469 ; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
470 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebx
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: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Reload
476 ; CHECK-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %rax ## 8-byte Folded Reload
477 ; CHECK-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r14 ## 8-byte Folded Reload
478 ; CHECK-NEXT: addq %rax, %r14
479 ; CHECK-NEXT: addq {{[-0-9]+}}(%r{{[sb]}}p), %r15 ## 8-byte Folded Reload
480 ; CHECK-NEXT: addq %r14, %r15
481 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
482 ; CHECK-NEXT: addq %rax, %r15
483 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
484 ; CHECK-NEXT: addq %rax, %rbx
485 ; CHECK-NEXT: addq %r15, %rbx
486 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
487 ; CHECK-NEXT: addq %rax, %r12
488 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
489 ; CHECK-NEXT: addq %rax, %r12
490 ; CHECK-NEXT: addq %rbx, %r12
491 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
492 ; CHECK-NEXT: addq %rax, %rbp
493 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
494 ; CHECK-NEXT: addq %rax, %rbp
495 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
496 ; CHECK-NEXT: addq %rax, %rbp
497 ; CHECK-NEXT: addq %r12, %rbp
498 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
499 ; CHECK-NEXT: addq %rax, %r13
500 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
501 ; CHECK-NEXT: addq %rax, %r13
502 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
503 ; CHECK-NEXT: addq %rax, %r13
504 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
505 ; CHECK-NEXT: addq %rax, %r13
506 ; CHECK-NEXT: addq %rbp, %r13
507 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ecx
508 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
509 ; CHECK-NEXT: addq %rax, %rcx
510 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
511 ; CHECK-NEXT: addq %rax, %rcx
512 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
513 ; CHECK-NEXT: addq %rax, %rcx
514 ; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
515 ; CHECK-NEXT: addq %rax, %rcx
516 ; CHECK-NEXT: addq %r13, %rcx
517 ; CHECK-NEXT: movq %rcx, %rax
518 ; CHECK-NEXT: addq $168, %rsp
519 ; CHECK-NEXT: popq %rbx
520 ; CHECK-NEXT: popq %r12
521 ; CHECK-NEXT: popq %r13
522 ; CHECK-NEXT: popq %r14
523 ; CHECK-NEXT: popq %r15
524 ; CHECK-NEXT: popq %rbp
528 %a64 = zext i32 %a to i64
529 %b64 = zext i32 %b to i64
530 %c64 = zext i32 %c to i64
531 %d64 = zext i32 %d to i64
532 %e64 = zext i32 %e to i64
533 %f64 = zext i32 %f to i64
534 %g64 = zext i32 %g to i64
535 %h64 = zext i32 %h to i64
536 %i64 = zext i32 %i to i64
537 %j64 = zext i32 %j to i64
538 %k64 = zext i32 %k to i64
539 %l64 = zext i32 %l to i64
540 %m64 = zext i32 %m to i64
541 %n64 = zext i32 %n to i64
542 %o64 = zext i32 %o to i64
543 %p64 = zext i32 %p to i64
544 %q64 = zext i32 %q to i64
545 %r64 = zext i32 %r to i64
546 %s64 = zext i32 %s to i64
547 %t64 = zext i32 %t to i64
548 %u64 = zext i32 %u to i64
549 %v64 = zext i32 %v to i64
550 %w64 = zext i32 %w to i64
551 %x64 = zext i32 %x to i64
552 %y64 = zext i32 %y to i64
553 %z64 = zext i32 %z to i64
554 call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(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)]
555 %addab = add i64 %a64, %b64
556 %addc = add i64 %addab, %c64
557 %addd = add i64 %addc, %d64
558 %adde = add i64 %addd, %e64
559 %addf = add i64 %adde, %f64
560 %addg = add i64 %addf, %g64
561 %addh = add i64 %addg, %h64
562 %addi = add i64 %addh, %i64
563 %addj = add i64 %addi, %j64
564 %addk = add i64 %addj, %k64
565 %addl = add i64 %addk, %l64
566 %addm = add i64 %addl, %m64
567 %addn = add i64 %addm, %n64
568 %addo = add i64 %addn, %o64
569 %addp = add i64 %addo, %p64
570 %addq = add i64 %addp, %q64
571 %addr = add i64 %addq, %r64
572 %adds = add i64 %addr, %s64
573 %addt = add i64 %adds, %t64
574 %addu = add i64 %addt, %u64
575 %addv = add i64 %addu, %v64
576 %addw = add i64 %addv, %w64
577 %addx = add i64 %addw, %x64
578 %addy = add i64 %addx, %y64
579 %addz = add i64 %addy, %z64
583 ; Demonstrate address of a function (w/o spilling)
584 define void @addr_func() gc "statepoint-example" {
585 ; CHECK-LABEL: addr_func:
586 ; CHECK: ## %bb.0: ## %entry
587 ; CHECK-NEXT: pushq %rax
588 ; CHECK-NEXT: .cfi_def_cfa_offset 16
589 ; CHECK-NEXT: movq _bar@GOTPCREL(%rip), %rax
590 ; CHECK-NEXT: callq _bar
591 ; CHECK-NEXT: Ltmp14:
592 ; CHECK-NEXT: popq %rax
595 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i64 0, i64 0) ["deopt"(ptr @bar, ptr @bar, ptr @bar)]
599 ; Demonstrate address of a global (w/o spilling)
600 @G = external global i32
601 define void @addr_global() gc "statepoint-example" {
602 ; CHECK-LABEL: addr_global:
603 ; CHECK: ## %bb.0: ## %entry
604 ; CHECK-NEXT: pushq %rax
605 ; CHECK-NEXT: .cfi_def_cfa_offset 16
606 ; CHECK-NEXT: movq _G@GOTPCREL(%rip), %rax
607 ; CHECK-NEXT: callq _bar
608 ; CHECK-NEXT: Ltmp15:
609 ; CHECK-NEXT: popq %rax
612 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i64 0, i64 0) ["deopt"(ptr @G, ptr @G, ptr @G)]
616 define void @addr_alloca(i32 %v) gc "statepoint-example" {
617 ; CHECK-LABEL: addr_alloca:
618 ; CHECK: ## %bb.0: ## %entry
619 ; CHECK-NEXT: pushq %rax
620 ; CHECK-NEXT: .cfi_def_cfa_offset 16
621 ; CHECK-NEXT: movl %edi, {{[0-9]+}}(%rsp)
622 ; CHECK-NEXT: callq _bar
623 ; CHECK-NEXT: Ltmp16:
624 ; CHECK-NEXT: popq %rax
629 %statepoint_token1 = call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 2882400000, i32 0, ptr elementtype(void ()) @bar, i32 0, i32 2, i64 0, i64 0) ["deopt"(ptr %a, ptr %a, ptr %a)]
634 ; CHECK: Ltmp0-_test1
636 ; CHECK-NEXT: .byte 0
637 ; CHECK-NEXT: .short 4
638 ; CHECK-NEXT: .short 5
639 ; CHECK-NEXT: .short 0
640 ; CHECK-NEXT: .long 0
642 ; CHECK: Ltmp1-_test2
644 ; CHECK-NEXT: .byte 0
645 ; CHECK-NEXT: .short 4
646 ; CHECK-NEXT: .short 6
647 ; CHECK-NEXT: .short 0
648 ; CHECK-NEXT: .long 0
650 ; CHECK-NEXT: .byte 0
651 ; CHECK-NEXT: .short 4
652 ; CHECK-NEXT: .short 3
653 ; CHECK-NEXT: .short 0
654 ; CHECK-NEXT: .long 0
655 ; CHECK: Ltmp2-_test2
657 ; CHECK-NEXT: .byte 0
658 ; CHECK-NEXT: .short 4
659 ; CHECK-NEXT: .short 3
660 ; CHECK-NEXT: .short 0
661 ; CHECK-NEXT: .long 0
663 ; CHECK-NEXT: .byte 0
664 ; CHECK-NEXT: .short 4
665 ; CHECK-NEXT: .short 6
666 ; CHECK-NEXT: .short 0
667 ; CHECK-NEXT: .long 0
669 declare token @llvm.experimental.gc.statepoint.p0(i64, i32, ptr, i32, i32, ...)
670 declare ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token, i32, i32)
672 attributes #0 = { "deopt-lowering"="live-in" }
673 attributes #1 = { "deopt-lowering"="live-through" }