| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc < %s -mtriple=arm64e-apple-macosx -o - | FileCheck %s | |
| ; Test that epilogue LR authentication uses the correct entry-SP modifier | |
| ; when local-frame teardown and callee-popped argument cleanup are combined | |
| ; into a single SP adjustment: the entry SP is reconstructed into a scratch | |
| ; register (x16) and authentication uses the register form of auti[ab] | |
| ; rather than auti[ab]sp, deferring the real SP adjustment to after aut. | |
| %large_struct = type { i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 } | |
| declare void @external_func() | |
| define swifttailcc void @test_frame_and_args(%large_struct %s) #0 { | |
| ; CHECK-LABEL: test_frame_and_args: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: pacibsp | |
| ; CHECK-NEXT: sub sp, sp, #80 | |
| ; CHECK-NEXT: str x30, [sp, #64] ; 8-byte Spill | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 80 | |
| ; CHECK-NEXT: .cfi_offset w30, -16 | |
| ; CHECK-NEXT: bl _external_func | |
| ; CHECK-NEXT: ldr x30, [sp, #64] ; 8-byte Reload | |
| ; CHECK-NEXT: add sp, sp, #144 | |
| ; CHECK-NEXT: sub x16, sp, #64 | |
| ; CHECK-NEXT: autib x30, x16 | |
| ; CHECK-NEXT: ret | |
| entry: | |
| %local1 = alloca [32 x i8], align 8 | |
| %local2 = alloca [32 x i8], align 8 | |
| call void @llvm.lifetime.start.p0(i64 32, ptr %local1) | |
| call void @llvm.lifetime.start.p0(i64 32, ptr %local2) | |
| call void @external_func() | |
| call void @llvm.lifetime.end.p0(i64 32, ptr %local2) | |
| call void @llvm.lifetime.end.p0(i64 32, ptr %local1) | |
| ret void | |
| } | |
| declare void @llvm.lifetime.start.p0(i64, ptr nocapture) | |
| declare void @llvm.lifetime.end.p0(i64, ptr nocapture) | |
| ; Test the same combined teardown when the callee-popped argument space is | |
| ; large enough that its cleanup is split into a shifted and unshifted parts. | |
| %large_struct2 = type { [600 x i64] } | |
| define swifttailcc void @test_frame_and_large_args(%large_struct2 %s) #0 { | |
| ; CHECK-LABEL: test_frame_and_large_args: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: pacibsp | |
| ; CHECK-NEXT: sub sp, sp, #48 | |
| ; CHECK-NEXT: stp x28, x30, [sp, #32] ; 16-byte Folded Spill | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 48 | |
| ; CHECK-NEXT: .cfi_offset w30, -8 | |
| ; CHECK-NEXT: .cfi_offset w28, -16 | |
| ; CHECK-NEXT: bl _external_func | |
| ; CHECK-NEXT: ldp x28, x30, [sp, #32] ; 16-byte Folded Reload | |
| ; CHECK-NEXT: add sp, sp, #1, lsl #12 ; =4096 | |
| ; CHECK-NEXT: add sp, sp, #688 | |
| ; CHECK-NEXT: sub x16, sp, #1, lsl #12 ; =4096 | |
| ; CHECK-NEXT: sub x16, x16, #640 | |
| ; CHECK-NEXT: autib x30, x16 | |
| ; CHECK-NEXT: ret | |
| entry: | |
| %local1 = alloca [32 x i8], align 8 | |
| call void @llvm.lifetime.start.p0(i64 32, ptr %local1) | |
| call void @external_func() | |
| call void @llvm.lifetime.end.p0(i64 32, ptr %local1) | |
| ret void | |
| } | |
| declare swifttailcc void @callee_stack0() | |
| declare void @use(ptr) | |
| define swifttailcc void @test_frame_and_args_split_by_csr_reload([8 x i64], i64 %x) "sign-return-address"="all" "frame-pointer"="all" uwtable(async) { | |
| ; CHECK-LABEL: test_frame_and_args_split_by_csr_reload: | |
| ; CHECK: ; %bb.0: ; %entry | |
| ; CHECK-NEXT: paciasp | |
| ; CHECK-NEXT: str x28, [sp, #-32]! ; 8-byte Folded Spill | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill | |
| ; CHECK-NEXT: add x29, sp, #16 | |
| ; CHECK-NEXT: .cfi_def_cfa w29, 16 | |
| ; CHECK-NEXT: .cfi_offset w30, -8 | |
| ; CHECK-NEXT: .cfi_offset w29, -16 | |
| ; CHECK-NEXT: .cfi_offset w28, -32 | |
| ; CHECK-NEXT: sub sp, sp, #1, lsl #12 ; =4096 | |
| ; CHECK-NEXT: sub sp, sp, #3904 | |
| ; CHECK-NEXT: mov x0, sp | |
| ; CHECK-NEXT: bl _use | |
| ; CHECK-NEXT: add sp, sp, #1, lsl #12 ; =4096 | |
| ; CHECK-NEXT: add sp, sp, #3904 | |
| ; CHECK-NEXT: .cfi_def_cfa wsp, 32 | |
| ; CHECK-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload | |
| ; CHECK-NEXT: ldr x28, [sp], #32 ; 8-byte Folded Reload | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 0 | |
| ; CHECK-NEXT: add sp, sp, #16 | |
| ; CHECK-NEXT: .cfi_def_cfa_offset -16 | |
| ; CHECK-NEXT: .cfi_restore w30 | |
| ; CHECK-NEXT: .cfi_restore w29 | |
| ; CHECK-NEXT: .cfi_restore w28 | |
| ; CHECK-NEXT: sub x16, sp, #16 | |
| ; CHECK-NEXT: autia x30, x16 | |
| ; CHECK-NEXT: b _callee_stack0 | |
| entry: | |
| %buf = alloca [8000 x i8], align 16 | |
| call void @use(ptr %buf) | |
| tail call swifttailcc void @callee_stack0() | |
| ret void | |
| } | |
| attributes #0 = { "ptrauth-returns" "sign-return-address"="all" "sign-return-address-key"="b_key" } |