; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2 | FileCheck %s --check-prefix=CHECK ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2,+ppx | FileCheck %s --check-prefix=PPX ; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+push2pop2 -frame-pointer=all | FileCheck %s --check-prefix=FRAME define void @csr1() nounwind { ; CHECK-LABEL: csr1: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rbp ; CHECK-NEXT: #APP ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: popq %rbp ; CHECK-NEXT: retq ; ; PPX-LABEL: csr1: ; PPX: # %bb.0: # %entry ; PPX-NEXT: pushp %rbp ; PPX-NEXT: #APP ; PPX-NEXT: #NO_APP ; PPX-NEXT: popp %rbp ; PPX-NEXT: retq ; ; FRAME-LABEL: csr1: ; FRAME: # %bb.0: # %entry ; FRAME-NEXT: pushq %rbp ; FRAME-NEXT: movq %rsp, %rbp ; FRAME-NEXT: #APP ; FRAME-NEXT: #NO_APP ; FRAME-NEXT: popq %rbp ; FRAME-NEXT: retq entry: tail call void asm sideeffect "", "~{rbp},~{dirflag},~{fpsr},~{flags}"() ret void } define void @csr2() nounwind { ; CHECK-LABEL: csr2: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rbp ; CHECK-NEXT: pushq %r15 ; CHECK-NEXT: #APP ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: popq %r15 ; CHECK-NEXT: popq %rbp ; CHECK-NEXT: retq ; ; PPX-LABEL: csr2: ; PPX: # %bb.0: # %entry ; PPX-NEXT: pushp %rbp ; PPX-NEXT: pushp %r15 ; PPX-NEXT: #APP ; PPX-NEXT: #NO_APP ; PPX-NEXT: popp %r15 ; PPX-NEXT: popp %rbp ; PPX-NEXT: retq ; ; FRAME-LABEL: csr2: ; FRAME: # %bb.0: # %entry ; FRAME-NEXT: pushq %rbp ; FRAME-NEXT: movq %rsp, %rbp ; FRAME-NEXT: pushq %r15 ; FRAME-NEXT: #APP ; FRAME-NEXT: #NO_APP ; FRAME-NEXT: popq %r15 ; FRAME-NEXT: popq %rbp ; FRAME-NEXT: retq entry: tail call void asm sideeffect "", "~{rbp},~{r15},~{dirflag},~{fpsr},~{flags}"() ret void } define void @csr3() nounwind { ; CHECK-LABEL: csr3: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rbp ; CHECK-NEXT: push2 %r14, %r15 ; CHECK-NEXT: #APP ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: pop2 %r15, %r14 ; CHECK-NEXT: popq %rbp ; CHECK-NEXT: retq ; ; PPX-LABEL: csr3: ; PPX: # %bb.0: # %entry ; PPX-NEXT: pushp %rbp ; PPX-NEXT: push2p %r14, %r15 ; PPX-NEXT: #APP ; PPX-NEXT: #NO_APP ; PPX-NEXT: pop2p %r15, %r14 ; PPX-NEXT: popp %rbp ; PPX-NEXT: retq ; ; FRAME-LABEL: csr3: ; FRAME: # %bb.0: # %entry ; FRAME-NEXT: pushq %rbp ; FRAME-NEXT: movq %rsp, %rbp ; FRAME-NEXT: push2 %r14, %r15 ; FRAME-NEXT: #APP ; FRAME-NEXT: #NO_APP ; FRAME-NEXT: pop2 %r15, %r14 ; FRAME-NEXT: popq %rbp ; FRAME-NEXT: retq entry: tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{dirflag},~{fpsr},~{flags}"() ret void } define void @csr4() nounwind { ; CHECK-LABEL: csr4: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: push2 %r15, %rbp ; CHECK-NEXT: push2 %r13, %r14 ; CHECK-NEXT: #APP ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: pop2 %r14, %r13 ; CHECK-NEXT: pop2 %rbp, %r15 ; CHECK-NEXT: popq %rax ; CHECK-NEXT: retq ; ; PPX-LABEL: csr4: ; PPX: # %bb.0: # %entry ; PPX-NEXT: pushq %rax ; PPX-NEXT: push2p %r15, %rbp ; PPX-NEXT: push2p %r13, %r14 ; PPX-NEXT: #APP ; PPX-NEXT: #NO_APP ; PPX-NEXT: pop2p %r14, %r13 ; PPX-NEXT: pop2p %rbp, %r15 ; PPX-NEXT: popq %rax ; PPX-NEXT: retq ; ; FRAME-LABEL: csr4: ; FRAME: # %bb.0: # %entry ; FRAME-NEXT: pushq %rbp ; FRAME-NEXT: movq %rsp, %rbp ; FRAME-NEXT: push2 %r14, %r15 ; FRAME-NEXT: pushq %r13 ; FRAME-NEXT: #APP ; FRAME-NEXT: #NO_APP ; FRAME-NEXT: popq %r13 ; FRAME-NEXT: pop2 %r15, %r14 ; FRAME-NEXT: popq %rbp ; FRAME-NEXT: retq entry: tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{dirflag},~{fpsr},~{flags}"() ret void } define void @csr5() nounwind { ; CHECK-LABEL: csr5: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rbp ; CHECK-NEXT: push2 %r14, %r15 ; CHECK-NEXT: push2 %r12, %r13 ; CHECK-NEXT: #APP ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: pop2 %r13, %r12 ; CHECK-NEXT: pop2 %r15, %r14 ; CHECK-NEXT: popq %rbp ; CHECK-NEXT: retq ; ; PPX-LABEL: csr5: ; PPX: # %bb.0: # %entry ; PPX-NEXT: pushp %rbp ; PPX-NEXT: push2p %r14, %r15 ; PPX-NEXT: push2p %r12, %r13 ; PPX-NEXT: #APP ; PPX-NEXT: #NO_APP ; PPX-NEXT: pop2p %r13, %r12 ; PPX-NEXT: pop2p %r15, %r14 ; PPX-NEXT: popp %rbp ; PPX-NEXT: retq ; ; FRAME-LABEL: csr5: ; FRAME: # %bb.0: # %entry ; FRAME-NEXT: pushq %rbp ; FRAME-NEXT: movq %rsp, %rbp ; FRAME-NEXT: push2 %r14, %r15 ; FRAME-NEXT: push2 %r12, %r13 ; FRAME-NEXT: #APP ; FRAME-NEXT: #NO_APP ; FRAME-NEXT: pop2 %r13, %r12 ; FRAME-NEXT: pop2 %r15, %r14 ; FRAME-NEXT: popq %rbp ; FRAME-NEXT: retq entry: tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{dirflag},~{fpsr},~{flags}"() ret void } define void @csr6() nounwind { ; CHECK-LABEL: csr6: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: push2 %r15, %rbp ; CHECK-NEXT: push2 %r13, %r14 ; CHECK-NEXT: push2 %rbx, %r12 ; CHECK-NEXT: #APP ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: pop2 %r12, %rbx ; CHECK-NEXT: pop2 %r14, %r13 ; CHECK-NEXT: pop2 %rbp, %r15 ; CHECK-NEXT: popq %rax ; CHECK-NEXT: retq ; ; PPX-LABEL: csr6: ; PPX: # %bb.0: # %entry ; PPX-NEXT: pushq %rax ; PPX-NEXT: push2p %r15, %rbp ; PPX-NEXT: push2p %r13, %r14 ; PPX-NEXT: push2p %rbx, %r12 ; PPX-NEXT: #APP ; PPX-NEXT: #NO_APP ; PPX-NEXT: pop2p %r12, %rbx ; PPX-NEXT: pop2p %r14, %r13 ; PPX-NEXT: pop2p %rbp, %r15 ; PPX-NEXT: popq %rax ; PPX-NEXT: retq ; ; FRAME-LABEL: csr6: ; FRAME: # %bb.0: # %entry ; FRAME-NEXT: pushq %rbp ; FRAME-NEXT: movq %rsp, %rbp ; FRAME-NEXT: push2 %r14, %r15 ; FRAME-NEXT: push2 %r12, %r13 ; FRAME-NEXT: pushq %rbx ; FRAME-NEXT: #APP ; FRAME-NEXT: #NO_APP ; FRAME-NEXT: popq %rbx ; FRAME-NEXT: pop2 %r13, %r12 ; FRAME-NEXT: pop2 %r15, %r14 ; FRAME-NEXT: popq %rbp ; FRAME-NEXT: retq entry: tail call void asm sideeffect "", "~{rbp},~{r15},~{r14},~{r13},~{r12},~{rbx},~{dirflag},~{fpsr},~{flags}"() ret void } declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) 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 { ; CHECK-LABEL: lea_in_epilog: ; CHECK: # %bb.0: # %bb ; CHECK-NEXT: testb $1, %dil ; CHECK-NEXT: je .LBB6_5 ; CHECK-NEXT: # %bb.1: # %bb13 ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: push2 %r15, %rbp ; CHECK-NEXT: push2 %r13, %r14 ; CHECK-NEXT: push2 %rbx, %r12 ; CHECK-NEXT: subq $16, %rsp ; CHECK-NEXT: movq %r9, %r14 ; CHECK-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill ; CHECK-NEXT: addq {{[0-9]+}}(%rsp), %r14 ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r13 ; CHECK-NEXT: addq %r14, %r13 ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r15 ; CHECK-NEXT: addq %r14, %r15 ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rbx ; CHECK-NEXT: addq %r14, %rbx ; CHECK-NEXT: xorl %ebp, %ebp ; CHECK-NEXT: xorl %r12d, %r12d ; CHECK-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill ; CHECK-NEXT: .p2align 4, 0x90 ; CHECK-NEXT: .LBB6_2: # %bb15 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: incq %r12 ; CHECK-NEXT: movl $432, %edx # imm = 0x1B0 ; CHECK-NEXT: xorl %edi, %edi ; CHECK-NEXT: movq %r15, %rsi ; CHECK-NEXT: callq memcpy@PLT ; CHECK-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax ; CHECK-NEXT: addq %rax, %r13 ; CHECK-NEXT: addq %rax, %r15 ; CHECK-NEXT: addq %rax, %rbx ; CHECK-NEXT: addq %rax, %r14 ; CHECK-NEXT: addq $8, %rbp ; CHECK-NEXT: testb $1, %dil ; CHECK-NEXT: je .LBB6_2 ; CHECK-NEXT: # %bb.3: # %bb11 ; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload ; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsp ; CHECK-NEXT: pop2 %r12, %rbx ; CHECK-NEXT: pop2 %r14, %r13 ; CHECK-NEXT: pop2 %rbp, %r15 ; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsp ; CHECK-NEXT: jne .LBB6_5 ; CHECK-NEXT: # %bb.4: # %bb12 ; CHECK-NEXT: movq $0, (%rax) ; CHECK-NEXT: .LBB6_5: # %bb14 ; CHECK-NEXT: retq ; ; PPX-LABEL: lea_in_epilog: ; PPX: # %bb.0: # %bb ; PPX-NEXT: testb $1, %dil ; PPX-NEXT: je .LBB6_5 ; PPX-NEXT: # %bb.1: # %bb13 ; PPX-NEXT: pushq %rax ; PPX-NEXT: push2p %r15, %rbp ; PPX-NEXT: push2p %r13, %r14 ; PPX-NEXT: push2p %rbx, %r12 ; PPX-NEXT: subq $16, %rsp ; PPX-NEXT: movq %r9, %r14 ; PPX-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill ; PPX-NEXT: addq {{[0-9]+}}(%rsp), %r14 ; PPX-NEXT: movq {{[0-9]+}}(%rsp), %r13 ; PPX-NEXT: addq %r14, %r13 ; PPX-NEXT: movq {{[0-9]+}}(%rsp), %r15 ; PPX-NEXT: addq %r14, %r15 ; PPX-NEXT: movq {{[0-9]+}}(%rsp), %rbx ; PPX-NEXT: addq %r14, %rbx ; PPX-NEXT: xorl %ebp, %ebp ; PPX-NEXT: xorl %r12d, %r12d ; PPX-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill ; PPX-NEXT: .p2align 4, 0x90 ; PPX-NEXT: .LBB6_2: # %bb15 ; PPX-NEXT: # =>This Inner Loop Header: Depth=1 ; PPX-NEXT: incq %r12 ; PPX-NEXT: movl $432, %edx # imm = 0x1B0 ; PPX-NEXT: xorl %edi, %edi ; PPX-NEXT: movq %r15, %rsi ; PPX-NEXT: callq memcpy@PLT ; PPX-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload ; PPX-NEXT: movq {{[0-9]+}}(%rsp), %rax ; PPX-NEXT: addq %rax, %r13 ; PPX-NEXT: addq %rax, %r15 ; PPX-NEXT: addq %rax, %rbx ; PPX-NEXT: addq %rax, %r14 ; PPX-NEXT: addq $8, %rbp ; PPX-NEXT: testb $1, %dil ; PPX-NEXT: je .LBB6_2 ; PPX-NEXT: # %bb.3: # %bb11 ; PPX-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload ; PPX-NEXT: leaq {{[0-9]+}}(%rsp), %rsp ; PPX-NEXT: pop2p %r12, %rbx ; PPX-NEXT: pop2p %r14, %r13 ; PPX-NEXT: pop2p %rbp, %r15 ; PPX-NEXT: leaq {{[0-9]+}}(%rsp), %rsp ; PPX-NEXT: jne .LBB6_5 ; PPX-NEXT: # %bb.4: # %bb12 ; PPX-NEXT: movq $0, (%rax) ; PPX-NEXT: .LBB6_5: # %bb14 ; PPX-NEXT: retq ; ; FRAME-LABEL: lea_in_epilog: ; FRAME: # %bb.0: # %bb ; FRAME-NEXT: testb $1, %dil ; FRAME-NEXT: je .LBB6_5 ; FRAME-NEXT: # %bb.1: # %bb13 ; FRAME-NEXT: pushq %rbp ; FRAME-NEXT: movq %rsp, %rbp ; FRAME-NEXT: push2 %r14, %r15 ; FRAME-NEXT: push2 %r12, %r13 ; FRAME-NEXT: pushq %rbx ; FRAME-NEXT: subq $24, %rsp ; FRAME-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill ; FRAME-NEXT: addq 16(%rbp), %r9 ; FRAME-NEXT: movq 48(%rbp), %rbx ; FRAME-NEXT: addq %r9, %rbx ; FRAME-NEXT: movq 40(%rbp), %r12 ; FRAME-NEXT: addq %r9, %r12 ; FRAME-NEXT: movq 32(%rbp), %r15 ; FRAME-NEXT: addq %r9, %r15 ; FRAME-NEXT: xorl %r13d, %r13d ; FRAME-NEXT: xorl %r14d, %r14d ; FRAME-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill ; FRAME-NEXT: .p2align 4, 0x90 ; FRAME-NEXT: .LBB6_2: # %bb15 ; FRAME-NEXT: # =>This Inner Loop Header: Depth=1 ; FRAME-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill ; FRAME-NEXT: incq %r14 ; FRAME-NEXT: movl $432, %edx # imm = 0x1B0 ; FRAME-NEXT: xorl %edi, %edi ; FRAME-NEXT: movq %r12, %rsi ; FRAME-NEXT: callq memcpy@PLT ; FRAME-NEXT: movl {{[-0-9]+}}(%r{{[sb]}}p), %edi # 4-byte Reload ; FRAME-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r9 # 8-byte Reload ; FRAME-NEXT: movq 16(%rbp), %rax ; FRAME-NEXT: addq %rax, %rbx ; FRAME-NEXT: addq %rax, %r12 ; FRAME-NEXT: addq %rax, %r15 ; FRAME-NEXT: addq %rax, %r9 ; FRAME-NEXT: addq $8, %r13 ; FRAME-NEXT: testb $1, %dil ; FRAME-NEXT: je .LBB6_2 ; FRAME-NEXT: # %bb.3: # %bb11 ; FRAME-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rax # 8-byte Reload ; FRAME-NEXT: leaq {{[0-9]+}}(%rsp), %rsp ; FRAME-NEXT: popq %rbx ; FRAME-NEXT: pop2 %r13, %r12 ; FRAME-NEXT: pop2 %r15, %r14 ; FRAME-NEXT: popq %rbp ; FRAME-NEXT: jne .LBB6_5 ; FRAME-NEXT: # %bb.4: # %bb12 ; FRAME-NEXT: movq $0, (%rax) ; FRAME-NEXT: .LBB6_5: # %bb14 ; FRAME-NEXT: retq bb: br i1 %arg, label %bb13, label %bb14 bb11: br i1 %arg, label %bb14, label %bb12 bb12: store double 0.000000e+00, ptr %arg1, align 8 br label %bb14 bb13: %getelementptr = getelementptr i8, ptr null, i64 %arg5 br label %bb15 bb14: ret void bb15: %phi = phi i64 [ 0, %bb13 ], [ %add, %bb15 ] %getelementptr16 = getelementptr double, ptr null, i64 %phi %add = add i64 %phi, 1 %mul = mul i64 %arg6, %add %getelementptr17 = getelementptr i8, ptr %getelementptr, i64 %mul call void @llvm.memcpy.p0.p0.i64(ptr %getelementptr16, ptr %getelementptr17, i64 0, i1 false) %getelementptr18 = getelementptr i8, ptr %getelementptr17, i64 %arg7 %getelementptr19 = getelementptr i8, ptr %getelementptr17, i64 %arg8 call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %getelementptr19, i64 0, i1 false) %getelementptr20 = getelementptr i8, ptr %getelementptr17, i64 %arg9 call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %getelementptr20, i64 432, i1 false) %getelementptr21 = getelementptr i8, ptr %getelementptr17, i64 %arg10 call void @llvm.memcpy.p0.p0.i64(ptr null, ptr %getelementptr21, i64 0, i1 false) br i1 %arg, label %bb11, label %bb15 }