[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / X86 / statepoint-live-in.ll
blobacc12f8e6283d4da61c4f02420dd73780a172f38
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, 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)
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, 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)
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, 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)
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, 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)
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  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
101 entry:
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
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, 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)
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, 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)
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, 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)
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, 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)
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, %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
394 entry:
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)
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, %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
530 entry:
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
583   ret i64 %addz
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
596 ; CHECK-NEXT:    retq
597 entry:
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)
599   ret void
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
613 ; CHECK-NEXT:    retq
614 entry:
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)
616   ret void
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
628 ; CHECK-NEXT:    retq
629 entry:
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 3, i32* %a, i32* %a, i32* %a)
633   ret void
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
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
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" }