1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2 | FileCheck %s --check-prefix=CHECK
3 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2,+ppx | FileCheck %s --check-prefix=PPX
4 ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2 -frame-pointer=all | FileCheck %s --check-prefix=FRAME
6 define void @csr1() nounwind {
8 ; CHECK: # %bb.0: # %entry
9 ; CHECK-NEXT: pushq %rbp
12 ; CHECK-NEXT: popq %rbp
16 ; PPX: # %bb.0: # %entry
17 ; PPX-NEXT: pushp %rbp
24 ; FRAME: # %bb.0: # %entry
25 ; FRAME-NEXT: pushq %rbp
26 ; FRAME-NEXT: movq %rsp, %rbp
29 ; FRAME-NEXT: popq %rbp
32 tail call void asm sideeffect "", "~{rbp},~{dirflag},~{fpsr},~{flags}"()
36 define void @csr2() nounwind {
38 ; CHECK: # %bb.0: # %entry
39 ; CHECK-NEXT: pushq %rbp
40 ; CHECK-NEXT: pushq %r15
43 ; CHECK-NEXT: popq %r15
44 ; CHECK-NEXT: popq %rbp
48 ; PPX: # %bb.0: # %entry
49 ; PPX-NEXT: pushp %rbp
50 ; PPX-NEXT: pushp %r15
58 ; FRAME: # %bb.0: # %entry
59 ; FRAME-NEXT: pushq %rbp
60 ; FRAME-NEXT: movq %rsp, %rbp
61 ; FRAME-NEXT: pushq %r15
64 ; FRAME-NEXT: popq %r15
65 ; FRAME-NEXT: popq %rbp
68 tail call void asm sideeffect "", "~{rbp},~{r15},~{dirflag},~{fpsr},~{flags}"()
72 define void @csr3() nounwind {
74 ; CHECK: # %bb.0: # %entry
75 ; CHECK-NEXT: pushq %rbp
76 ; CHECK-NEXT: push2 %r14, %r15
79 ; CHECK-NEXT: pop2 %r15, %r14
80 ; CHECK-NEXT: popq %rbp
84 ; PPX: # %bb.0: # %entry
85 ; PPX-NEXT: pushp %rbp
86 ; PPX-NEXT: push2p %r14, %r15
89 ; PPX-NEXT: pop2p %r15, %r14
94 ; FRAME: # %bb.0: # %entry
95 ; FRAME-NEXT: pushq %rbp
96 ; FRAME-NEXT: movq %rsp, %rbp
97 ; FRAME-NEXT: push2 %r14, %r15
100 ; FRAME-NEXT: pop2 %r15, %r14
101 ; FRAME-NEXT: popq %rbp
104 tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{dirflag},~{fpsr},~{flags}"()
108 define void @csr4() nounwind {
110 ; CHECK: # %bb.0: # %entry
111 ; CHECK-NEXT: pushq %rax
112 ; CHECK-NEXT: push2 %r15, %rbp
113 ; CHECK-NEXT: push2 %r13, %r14
115 ; CHECK-NEXT: #NO_APP
116 ; CHECK-NEXT: pop2 %r14, %r13
117 ; CHECK-NEXT: pop2 %rbp, %r15
118 ; CHECK-NEXT: popq %rax
122 ; PPX: # %bb.0: # %entry
123 ; PPX-NEXT: pushq %rax
124 ; PPX-NEXT: push2p %r15, %rbp
125 ; PPX-NEXT: push2p %r13, %r14
128 ; PPX-NEXT: pop2p %r14, %r13
129 ; PPX-NEXT: pop2p %rbp, %r15
130 ; PPX-NEXT: popq %rax
134 ; FRAME: # %bb.0: # %entry
135 ; FRAME-NEXT: pushq %rbp
136 ; FRAME-NEXT: movq %rsp, %rbp
137 ; FRAME-NEXT: push2 %r14, %r15
138 ; FRAME-NEXT: pushq %r13
140 ; FRAME-NEXT: #NO_APP
141 ; FRAME-NEXT: popq %r13
142 ; FRAME-NEXT: pop2 %r15, %r14
143 ; FRAME-NEXT: popq %rbp
146 tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{dirflag},~{fpsr},~{flags}"()
150 define void @csr5() nounwind {
152 ; CHECK: # %bb.0: # %entry
153 ; CHECK-NEXT: pushq %rbp
154 ; CHECK-NEXT: push2 %r14, %r15
155 ; CHECK-NEXT: push2 %r12, %r13
157 ; CHECK-NEXT: #NO_APP
158 ; CHECK-NEXT: pop2 %r13, %r12
159 ; CHECK-NEXT: pop2 %r15, %r14
160 ; CHECK-NEXT: popq %rbp
164 ; PPX: # %bb.0: # %entry
165 ; PPX-NEXT: pushp %rbp
166 ; PPX-NEXT: push2p %r14, %r15
167 ; PPX-NEXT: push2p %r12, %r13
170 ; PPX-NEXT: pop2p %r13, %r12
171 ; PPX-NEXT: pop2p %r15, %r14
172 ; PPX-NEXT: popp %rbp
176 ; FRAME: # %bb.0: # %entry
177 ; FRAME-NEXT: pushq %rbp
178 ; FRAME-NEXT: movq %rsp, %rbp
179 ; FRAME-NEXT: push2 %r14, %r15
180 ; FRAME-NEXT: push2 %r12, %r13
182 ; FRAME-NEXT: #NO_APP
183 ; FRAME-NEXT: pop2 %r13, %r12
184 ; FRAME-NEXT: pop2 %r15, %r14
185 ; FRAME-NEXT: popq %rbp
188 tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{dirflag},~{fpsr},~{flags}"()
192 define void @csr6() nounwind {
194 ; CHECK: # %bb.0: # %entry
195 ; CHECK-NEXT: pushq %rax
196 ; CHECK-NEXT: push2 %r15, %rbp
197 ; CHECK-NEXT: push2 %r13, %r14
198 ; CHECK-NEXT: push2 %rbx, %r12
200 ; CHECK-NEXT: #NO_APP
201 ; CHECK-NEXT: pop2 %r12, %rbx
202 ; CHECK-NEXT: pop2 %r14, %r13
203 ; CHECK-NEXT: pop2 %rbp, %r15
204 ; CHECK-NEXT: popq %rax
208 ; PPX: # %bb.0: # %entry
209 ; PPX-NEXT: pushq %rax
210 ; PPX-NEXT: push2p %r15, %rbp
211 ; PPX-NEXT: push2p %r13, %r14
212 ; PPX-NEXT: push2p %rbx, %r12
215 ; PPX-NEXT: pop2p %r12, %rbx
216 ; PPX-NEXT: pop2p %r14, %r13
217 ; PPX-NEXT: pop2p %rbp, %r15
218 ; PPX-NEXT: popq %rax
222 ; FRAME: # %bb.0: # %entry
223 ; FRAME-NEXT: pushq %rbp
224 ; FRAME-NEXT: movq %rsp, %rbp
225 ; FRAME-NEXT: push2 %r14, %r15
226 ; FRAME-NEXT: push2 %r12, %r13
227 ; FRAME-NEXT: pushq %rbx
229 ; FRAME-NEXT: #NO_APP
230 ; FRAME-NEXT: popq %rbx
231 ; FRAME-NEXT: pop2 %r13, %r12
232 ; FRAME-NEXT: pop2 %r15, %r14
233 ; FRAME-NEXT: popq %rbp
236 tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{rbx},~{dirflag},~{fpsr},~{flags}"()
240 declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)
242 define void @lea_in_epilog(i1 %arg, ptr %arg1, ptr %arg2, i64 %arg3, i64 %arg4, i64 %arg5, i64 %arg6, i64 %arg7, i64 %arg8, i64 %arg9, i64 %arg10) nounwind {
243 ; CHECK-LABEL: lea_in_epilog:
244 ; CHECK: # %bb.0: # %bb
245 ; CHECK-NEXT: testb $1, %dil
246 ; CHECK-NEXT: je .LBB6_5
247 ; CHECK-NEXT: # %bb.1: # %bb13
248 ; CHECK-NEXT: pushq %rax
249 ; CHECK-NEXT: push2 %r15, %rbp
250 ; CHECK-NEXT: push2 %r13, %r14
251 ; CHECK-NEXT: push2 %rbx, %r12
252 ; CHECK-NEXT: subq $16, %rsp
253 ; CHECK-NEXT: movq %r9, %r14
254 ; CHECK-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
255 ; CHECK-NEXT: addq {{[0-9]+}}(%rsp), %r14
256 ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r13
257 ; CHECK-NEXT: addq %r14, %r13
258 ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r15
259 ; CHECK-NEXT: addq %r14, %r15
260 ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rbx
261 ; CHECK-NEXT: addq %r14, %rbx
262 ; CHECK-NEXT: xorl %ebp, %ebp
263 ; CHECK-NEXT: xorl %r12d, %r12d
264 ; CHECK-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
265 ; CHECK-NEXT: .p2align 4, 0x90
266 ; CHECK-NEXT: .LBB6_2: # %bb15
267 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
268 ; CHECK-NEXT: incq %r12
269 ; CHECK-NEXT: movl $432, %edx # imm = 0x1B0
270 ; CHECK-NEXT: xorl %edi, %edi
271 ; CHECK-NEXT: movq %r15, %rsi
272 ; CHECK-NEXT: callq memcpy@PLT
273 ; CHECK-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
274 ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax
275 ; CHECK-NEXT: addq %rax, %r13
276 ; CHECK-NEXT: addq %rax, %r15
277 ; CHECK-NEXT: addq %rax, %rbx
278 ; CHECK-NEXT: addq %rax, %r14
279 ; CHECK-NEXT: addq $8, %rbp
280 ; CHECK-NEXT: testb $1, %dil
281 ; CHECK-NEXT: je .LBB6_2
282 ; CHECK-NEXT: # %bb.3: # %bb11
283 ; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
284 ; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsp
285 ; CHECK-NEXT: pop2 %r12, %rbx
286 ; CHECK-NEXT: pop2 %r14, %r13
287 ; CHECK-NEXT: pop2 %rbp, %r15
288 ; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsp
289 ; CHECK-NEXT: jne .LBB6_5
290 ; CHECK-NEXT: # %bb.4: # %bb12
291 ; CHECK-NEXT: movq $0, (%rax)
292 ; CHECK-NEXT: .LBB6_5: # %bb14
295 ; PPX-LABEL: lea_in_epilog:
296 ; PPX: # %bb.0: # %bb
297 ; PPX-NEXT: testb $1, %dil
298 ; PPX-NEXT: je .LBB6_5
299 ; PPX-NEXT: # %bb.1: # %bb13
300 ; PPX-NEXT: pushq %rax
301 ; PPX-NEXT: push2p %r15, %rbp
302 ; PPX-NEXT: push2p %r13, %r14
303 ; PPX-NEXT: push2p %rbx, %r12
304 ; PPX-NEXT: subq $16, %rsp
305 ; PPX-NEXT: movq %r9, %r14
306 ; PPX-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
307 ; PPX-NEXT: addq {{[0-9]+}}(%rsp), %r14
308 ; PPX-NEXT: movq {{[0-9]+}}(%rsp), %r13
309 ; PPX-NEXT: addq %r14, %r13
310 ; PPX-NEXT: movq {{[0-9]+}}(%rsp), %r15
311 ; PPX-NEXT: addq %r14, %r15
312 ; PPX-NEXT: movq {{[0-9]+}}(%rsp), %rbx
313 ; PPX-NEXT: addq %r14, %rbx
314 ; PPX-NEXT: xorl %ebp, %ebp
315 ; PPX-NEXT: xorl %r12d, %r12d
316 ; PPX-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
317 ; PPX-NEXT: .p2align 4, 0x90
318 ; PPX-NEXT: .LBB6_2: # %bb15
319 ; PPX-NEXT: # =>This Inner Loop Header: Depth=1
320 ; PPX-NEXT: incq %r12
321 ; PPX-NEXT: movl $432, %edx # imm = 0x1B0
322 ; PPX-NEXT: xorl %edi, %edi
323 ; PPX-NEXT: movq %r15, %rsi
324 ; PPX-NEXT: callq memcpy@PLT
325 ; PPX-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
326 ; PPX-NEXT: movq {{[0-9]+}}(%rsp), %rax
327 ; PPX-NEXT: addq %rax, %r13
328 ; PPX-NEXT: addq %rax, %r15
329 ; PPX-NEXT: addq %rax, %rbx
330 ; PPX-NEXT: addq %rax, %r14
331 ; PPX-NEXT: addq $8, %rbp
332 ; PPX-NEXT: testb $1, %dil
333 ; PPX-NEXT: je .LBB6_2
334 ; PPX-NEXT: # %bb.3: # %bb11
335 ; PPX-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
336 ; PPX-NEXT: leaq {{[0-9]+}}(%rsp), %rsp
337 ; PPX-NEXT: pop2p %r12, %rbx
338 ; PPX-NEXT: pop2p %r14, %r13
339 ; PPX-NEXT: pop2p %rbp, %r15
340 ; PPX-NEXT: leaq {{[0-9]+}}(%rsp), %rsp
341 ; PPX-NEXT: jne .LBB6_5
342 ; PPX-NEXT: # %bb.4: # %bb12
343 ; PPX-NEXT: movq $0, (%rax)
344 ; PPX-NEXT: .LBB6_5: # %bb14
347 ; FRAME-LABEL: lea_in_epilog:
348 ; FRAME: # %bb.0: # %bb
349 ; FRAME-NEXT: testb $1, %dil
350 ; FRAME-NEXT: je .LBB6_5
351 ; FRAME-NEXT: # %bb.1: # %bb13
352 ; FRAME-NEXT: pushq %rbp
353 ; FRAME-NEXT: movq %rsp, %rbp
354 ; FRAME-NEXT: push2 %r14, %r15
355 ; FRAME-NEXT: push2 %r12, %r13
356 ; FRAME-NEXT: pushq %rbx
357 ; FRAME-NEXT: subq $24, %rsp
358 ; FRAME-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
359 ; FRAME-NEXT: addq 16(%rbp), %r9
360 ; FRAME-NEXT: movq 48(%rbp), %rbx
361 ; FRAME-NEXT: addq %r9, %rbx
362 ; FRAME-NEXT: movq 40(%rbp), %r12
363 ; FRAME-NEXT: addq %r9, %r12
364 ; FRAME-NEXT: movq 32(%rbp), %r15
365 ; FRAME-NEXT: addq %r9, %r15
366 ; FRAME-NEXT: xorl %r13d, %r13d
367 ; FRAME-NEXT: xorl %r14d, %r14d
368 ; FRAME-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
369 ; FRAME-NEXT: .p2align 4, 0x90
370 ; FRAME-NEXT: .LBB6_2: # %bb15
371 ; FRAME-NEXT: # =>This Inner Loop Header: Depth=1
372 ; FRAME-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill
373 ; FRAME-NEXT: incq %r14
374 ; FRAME-NEXT: movl $432, %edx # imm = 0x1B0
375 ; FRAME-NEXT: xorl %edi, %edi
376 ; FRAME-NEXT: movq %r12, %rsi
377 ; FRAME-NEXT: callq memcpy@PLT
378 ; FRAME-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload
379 ; FRAME-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Reload
380 ; FRAME-NEXT: movq 16(%rbp), %rax
381 ; FRAME-NEXT: addq %rax, %rbx
382 ; FRAME-NEXT: addq %rax, %r12
383 ; FRAME-NEXT: addq %rax, %r15
384 ; FRAME-NEXT: addq %rax, %r9
385 ; FRAME-NEXT: addq $8, %r13
386 ; FRAME-NEXT: testb $1, %dil
387 ; FRAME-NEXT: je .LBB6_2
388 ; FRAME-NEXT: # %bb.3: # %bb11
389 ; FRAME-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload
390 ; FRAME-NEXT: leaq {{[0-9]+}}(%rsp), %rsp
391 ; FRAME-NEXT: popq %rbx
392 ; FRAME-NEXT: pop2 %r13, %r12
393 ; FRAME-NEXT: pop2 %r15, %r14
394 ; FRAME-NEXT: popq %rbp
395 ; FRAME-NEXT: jne .LBB6_5
396 ; FRAME-NEXT: # %bb.4: # %bb12
397 ; FRAME-NEXT: movq $0, (%rax)
398 ; FRAME-NEXT: .LBB6_5: # %bb14
401 br i1 %arg, label %bb13, label %bb14
404 br i1 %arg, label %bb14, label %bb12
407 store double 0.000000e+00, ptr %arg1, align 8
411 %getelementptr = getelementptr i8, ptr null, i64 %arg5
418 %phi = phi i64 [ 0, %bb13 ], [ %add, %bb15 ]
419 %getelementptr16 = getelementptr double, ptr null, i64 %phi
420 %add = add i64 %phi, 1
421 %mul = mul i64 %arg6, %add
422 %getelementptr17 = getelementptr i8, ptr %getelementptr, i64 %mul
423 call void @llvm.memcpy.p0.p0.i64(ptr %getelementptr16, ptr %getelementptr17, i64 0, i1 false)
424 %getelementptr18 = getelementptr i8, ptr %getelementptr17, i64 %arg7
425 %getelementptr19 = getelementptr i8, ptr %getelementptr17, i64 %arg8
426 call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %getelementptr19, i64 0, i1 false)
427 %getelementptr20 = getelementptr i8, ptr %getelementptr17, i64 %arg9
428 call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %getelementptr20, i64 432, i1 false)
429 %getelementptr21 = getelementptr i8, ptr %getelementptr17, i64 %arg10
430 call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %getelementptr21, i64 0, i1 false)
431 br i1 %arg, label %bb11, label %bb15