Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / X86 / statepoint-live-in.ll
blob787a33aa49b20e4071a234d35666c57eb9161c64
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"
6 declare void @bar() #0
7 declare void @baz()
9 define 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
18 entry:
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)]
21   ret void
24 define 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
45 entry:
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)]
50   ret void
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" {
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
62 entry:
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)]
65   ret void
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" {
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
81 entry:
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)]
83   ret void
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" {
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
101 entry:
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
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
125 entry:
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)]
128   ret void
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
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
204 entry:
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)]
232   ret void
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
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
299 entry:
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)]
327   ret void
330 ; Test perfect forwarding of argument registers and stack slots to the
331 ; deopt bundle uses
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
340 ; CHECK-NEXT:    retq
342 entry:
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)]
344   ret void
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
392 ; CHECK-NEXT:    retq
394 entry:
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)]
397   ret void
400 ; Check that we can remat some uses of a def despite not remating before the
401 ; statepoint user.
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
525 ; CHECK-NEXT:    retq
527 entry:
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
580   ret i64 %addz
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
593 ; CHECK-NEXT:    retq
594 entry:
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)]
596   ret void
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
610 ; CHECK-NEXT:    retq
611 entry:
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)]
613   ret void
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
625 ; CHECK-NEXT:    retq
626 entry:
627   %a = alloca i32
628   store i32 %v, ptr %a
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)]
630   ret void
634 ; CHECK: Ltmp0-_test1
635 ; CHECK:      .byte     1
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
643 ; CHECK:      .byte     1
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
649 ; CHECK:      .byte     1
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
656 ; CHECK:      .byte     1
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
662 ; CHECK:      .byte     1
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" }