| ; 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 |
| } |