diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 666ff8bbab42a..00fbeef9d35df 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1746,7 +1746,7 @@ static void emitShadowCallStackEpilogue(const TargetInstrInfo &TII, MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - const DebugLoc &DL) { + const DebugLoc &DL, bool NeedsWinCFI) { // Shadow call stack epilog: ldr x30, [x18, #-8]! BuildMI(MBB, MBBI, DL, TII.get(AArch64::LDRXpre)) .addReg(AArch64::X18, RegState::Define) @@ -1755,6 +1755,10 @@ static void emitShadowCallStackEpilogue(const TargetInstrInfo &TII, .addImm(-8) .setMIFlag(MachineInstr::FrameDestroy); + if (NeedsWinCFI) + BuildMI(MBB, MBBI, DL, TII.get(AArch64::SEH_Nop)) + .setMIFlag(MachineInstr::FrameDestroy); + if (MF.getInfo()->needsAsyncDwarfUnwindInfo(MF)) CFIInstBuilder(MBB, MBBI, MachineInstr::FrameDestroy) .buildRestore(AArch64::X18); @@ -1899,13 +1903,15 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE)) .setMIFlag(MachineInstr::FrameSetup); } - if (NeedsWinCFI) - HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR + // AArch64PointerAuth pass will insert SEH_PACSignLR + HasWinCFI |= NeedsWinCFI; } - if (MFnI.needsShadowCallStackPrologueEpilogue(MF)) + if (MFnI.needsShadowCallStackPrologueEpilogue(MF)) { emitShadowCallStackPrologue(*TII, MF, MBB, MBBI, DL, NeedsWinCFI, MFnI.needsDwarfUnwindInfo(MF)); + HasWinCFI |= NeedsWinCFI; + } if (EmitCFI && MFnI.isMTETagged()) { BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITMTETAGGED)) @@ -1990,8 +1996,13 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF, "unexpected function without stack frame but with SVE objects"); // All of the stack allocation is for locals. AFI->setLocalStackSize(NumBytes); - if (!NumBytes) + if (!NumBytes) { + if (NeedsWinCFI && HasWinCFI) { + BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd)) + .setMIFlag(MachineInstr::FrameSetup); + } return; + } // REDZONE: If the stack size is less than 128 bytes, we don't need // to actually allocate. if (canUseRedZone(MF)) { @@ -2460,8 +2471,11 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock::iterator EpilogStartI = MBB.end(); auto FinishingTouches = make_scope_exit([&]() { - if (AFI->needsShadowCallStackPrologueEpilogue(MF)) - emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL); + if (AFI->needsShadowCallStackPrologueEpilogue(MF)) { + emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL, + NeedsWinCFI); + HasWinCFI |= NeedsWinCFI; + } if (EmitCFI) emitCalleeSavedGPRRestores(MBB, MBB.getFirstTerminator()); if (AFI->shouldSignReturnAddress(MF)) { @@ -2472,8 +2486,8 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF, TII->get(AArch64::PAUTH_EPILOGUE)) .setMIFlag(MachineInstr::FrameDestroy); } - if (NeedsWinCFI) - HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR + // AArch64PointerAuth pass will insert SEH_PACSignLR + HasWinCFI |= NeedsWinCFI; } if (HasWinCFI) { BuildMI(MBB, MBB.getFirstTerminator(), DL, diff --git a/llvm/test/CodeGen/AArch64/sign-return-address.ll b/llvm/test/CodeGen/AArch64/sign-return-address.ll index b0ab4775cb388..7267ce0e3afbf 100644 --- a/llvm/test/CodeGen/AArch64/sign-return-address.ll +++ b/llvm/test/CodeGen/AArch64/sign-return-address.ll @@ -1,9 +1,18 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 -; RUN: llc -mtriple=aarch64 < %s | FileCheck --check-prefixes=CHECK,COMPAT %s -; RUN: llc -mtriple=aarch64 -mattr=v8.3a < %s | FileCheck --check-prefixes=CHECK,V83A %s +; RUN: llc -mtriple=aarch64 < %s | FileCheck --check-prefixes=CHECK,DWARFCFI,DWARFCFI-COMPAT %s +; RUN: llc -mtriple=aarch64 -mattr=v8.3a < %s | FileCheck --check-prefixes=CHECK,DWARFCFI,DWARFCFI-V83A %s -; v9.5-A is not expected to change codegen without -mbranch-protection=+pc, so reuse V83A. -; RUN: llc -mtriple=aarch64 -mattr=v9.5a < %s | FileCheck --check-prefixes=CHECK,V83A %s +; v9.5-A is not expected to change codegen without -mbranch-protection=+pc, so reuse DWARFCFI-V83A. +; RUN: llc -mtriple=aarch64 -mattr=v9.5a < %s | FileCheck --check-prefixes=CHECK,DWARFCFI,DWARFCFI-V83A %s + +; RUN: llc -mtriple=aarch64-windows < %s | FileCheck --check-prefixes=CHECK,WINCFI,WINCFI-COMPAT %s +; RUN: llc -mtriple=aarch64-windows -mattr=v8.3a < %s | FileCheck --check-prefixes=CHECK,WINCFI,WINCFI-V83A %s + +; Make sure no errors are detected when emitting SEH opcodes. +; Errors are only checked for when generating a binary, so emit a dummy object +; file and make sure llc produces zero exit code. +; RUN: llc -mtriple=aarch64-windows -o %t.dummy.o --filetype=obj < %s +; RUN: llc -mtriple=aarch64-windows -mattr=v8.3a -o %t.dummy.o --filetype=obj < %s define i32 @leaf(i32 %x) { ; CHECK-LABEL: leaf: @@ -27,48 +36,118 @@ define i32 @leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" { } define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" { -; COMPAT-LABEL: leaf_sign_all: -; COMPAT: // %bb.0: -; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: hint #29 -; COMPAT-NEXT: ret -; -; V83A-LABEL: leaf_sign_all: -; V83A: // %bb.0: -; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: retaa +; DWARFCFI-COMPAT-LABEL: leaf_sign_all: +; DWARFCFI-COMPAT: // %bb.0: +; DWARFCFI-COMPAT-NEXT: hint #25 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: hint #29 +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: leaf_sign_all: +; DWARFCFI-V83A: // %bb.0: +; DWARFCFI-V83A-NEXT: paciasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: retaa +; +; WINCFI-COMPAT-LABEL: leaf_sign_all: +; WINCFI-COMPAT: .seh_proc leaf_sign_all +; WINCFI-COMPAT-NEXT: // %bb.0: +; WINCFI-COMPAT-NEXT: hint #27 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: hint #31 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: leaf_sign_all: +; WINCFI-V83A: .seh_proc leaf_sign_all +; WINCFI-V83A-NEXT: // %bb.0: +; WINCFI-V83A-NEXT: pacibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: autibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc ret i32 %x } define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" { -; COMPAT-LABEL: leaf_clobbers_lr: -; COMPAT: // %bb.0: -; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_def_cfa_offset 16 -; COMPAT-NEXT: .cfi_offset w30, -16 -; COMPAT-NEXT: //APP -; COMPAT-NEXT: mov x30, x0 -; COMPAT-NEXT: //NO_APP -; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: hint #29 -; COMPAT-NEXT: ret -; -; V83A-LABEL: leaf_clobbers_lr: -; V83A: // %bb.0: -; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_def_cfa_offset 16 -; V83A-NEXT: .cfi_offset w30, -16 -; V83A-NEXT: //APP -; V83A-NEXT: mov x30, x0 -; V83A-NEXT: //NO_APP -; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: retaa +; DWARFCFI-COMPAT-LABEL: leaf_clobbers_lr: +; DWARFCFI-COMPAT: // %bb.0: +; DWARFCFI-COMPAT-NEXT: hint #25 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-COMPAT-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-COMPAT-NEXT: .cfi_offset w30, -16 +; DWARFCFI-COMPAT-NEXT: //APP +; DWARFCFI-COMPAT-NEXT: mov x30, x0 +; DWARFCFI-COMPAT-NEXT: //NO_APP +; DWARFCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-COMPAT-NEXT: hint #29 +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: leaf_clobbers_lr: +; DWARFCFI-V83A: // %bb.0: +; DWARFCFI-V83A-NEXT: paciasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-V83A-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-V83A-NEXT: .cfi_offset w30, -16 +; DWARFCFI-V83A-NEXT: //APP +; DWARFCFI-V83A-NEXT: mov x30, x0 +; DWARFCFI-V83A-NEXT: //NO_APP +; DWARFCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-V83A-NEXT: retaa +; +; WINCFI-COMPAT-LABEL: leaf_clobbers_lr: +; WINCFI-COMPAT: .seh_proc leaf_clobbers_lr +; WINCFI-COMPAT-NEXT: // %bb.0: +; WINCFI-COMPAT-NEXT: hint #27 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: //APP +; WINCFI-COMPAT-NEXT: mov x30, x0 +; WINCFI-COMPAT-NEXT: //NO_APP +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: hint #31 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: leaf_clobbers_lr: +; WINCFI-V83A: .seh_proc leaf_clobbers_lr +; WINCFI-V83A-NEXT: // %bb.0: +; WINCFI-V83A-NEXT: pacibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: //APP +; WINCFI-V83A-NEXT: mov x30, x0 +; WINCFI-V83A-NEXT: //NO_APP +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: autibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1 ret i64 %x } @@ -76,75 +155,174 @@ define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" { declare i32 @foo(i32) define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" { -; COMPAT-LABEL: non_leaf_sign_all: -; COMPAT: // %bb.0: -; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_def_cfa_offset 16 -; COMPAT-NEXT: .cfi_offset w30, -16 -; COMPAT-NEXT: bl foo -; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: hint #29 -; COMPAT-NEXT: ret -; -; V83A-LABEL: non_leaf_sign_all: -; V83A: // %bb.0: -; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_def_cfa_offset 16 -; V83A-NEXT: .cfi_offset w30, -16 -; V83A-NEXT: bl foo -; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: retaa +; DWARFCFI-COMPAT-LABEL: non_leaf_sign_all: +; DWARFCFI-COMPAT: // %bb.0: +; DWARFCFI-COMPAT-NEXT: hint #25 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-COMPAT-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-COMPAT-NEXT: .cfi_offset w30, -16 +; DWARFCFI-COMPAT-NEXT: bl foo +; DWARFCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-COMPAT-NEXT: hint #29 +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: non_leaf_sign_all: +; DWARFCFI-V83A: // %bb.0: +; DWARFCFI-V83A-NEXT: paciasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-V83A-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-V83A-NEXT: .cfi_offset w30, -16 +; DWARFCFI-V83A-NEXT: bl foo +; DWARFCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-V83A-NEXT: retaa +; +; WINCFI-COMPAT-LABEL: non_leaf_sign_all: +; WINCFI-COMPAT: .seh_proc non_leaf_sign_all +; WINCFI-COMPAT-NEXT: // %bb.0: +; WINCFI-COMPAT-NEXT: hint #27 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: bl foo +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: hint #31 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: non_leaf_sign_all: +; WINCFI-V83A: .seh_proc non_leaf_sign_all +; WINCFI-V83A-NEXT: // %bb.0: +; WINCFI-V83A-NEXT: pacibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: bl foo +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: autibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc %call = call i32 @foo(i32 %x) ret i32 %call } define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" { -; COMPAT-LABEL: non_leaf_sign_non_leaf: -; COMPAT: // %bb.0: -; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_def_cfa_offset 16 -; COMPAT-NEXT: .cfi_offset w30, -16 -; COMPAT-NEXT: bl foo -; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: hint #29 -; COMPAT-NEXT: ret -; -; V83A-LABEL: non_leaf_sign_non_leaf: -; V83A: // %bb.0: -; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_def_cfa_offset 16 -; V83A-NEXT: .cfi_offset w30, -16 -; V83A-NEXT: bl foo -; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: retaa +; DWARFCFI-COMPAT-LABEL: non_leaf_sign_non_leaf: +; DWARFCFI-COMPAT: // %bb.0: +; DWARFCFI-COMPAT-NEXT: hint #25 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-COMPAT-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-COMPAT-NEXT: .cfi_offset w30, -16 +; DWARFCFI-COMPAT-NEXT: bl foo +; DWARFCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-COMPAT-NEXT: hint #29 +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: non_leaf_sign_non_leaf: +; DWARFCFI-V83A: // %bb.0: +; DWARFCFI-V83A-NEXT: paciasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-V83A-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-V83A-NEXT: .cfi_offset w30, -16 +; DWARFCFI-V83A-NEXT: bl foo +; DWARFCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-V83A-NEXT: retaa +; +; WINCFI-COMPAT-LABEL: non_leaf_sign_non_leaf: +; WINCFI-COMPAT: .seh_proc non_leaf_sign_non_leaf +; WINCFI-COMPAT-NEXT: // %bb.0: +; WINCFI-COMPAT-NEXT: hint #27 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: bl foo +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: hint #31 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: non_leaf_sign_non_leaf: +; WINCFI-V83A: .seh_proc non_leaf_sign_non_leaf +; WINCFI-V83A-NEXT: // %bb.0: +; WINCFI-V83A-NEXT: pacibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: bl foo +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: autibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc %call = call i32 @foo(i32 %x) ret i32 %call } ; Should not use the RETAA instruction. define i32 @non_leaf_scs(i32 %x) "sign-return-address"="non-leaf" shadowcallstack "target-features"="+v8.3a,+reserve-x18" { -; CHECK-LABEL: non_leaf_scs: -; CHECK: // %bb.0: -; CHECK-NEXT: paciasp -; CHECK-NEXT: .cfi_negate_ra_state -; CHECK-NEXT: str x30, [x18], #8 -; CHECK-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 // -; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: .cfi_offset w30, -16 -; CHECK-NEXT: bl foo -; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; CHECK-NEXT: ldr x30, [x18, #-8]! -; CHECK-NEXT: autiasp -; CHECK-NEXT: ret +; DWARFCFI-LABEL: non_leaf_scs: +; DWARFCFI: // %bb.0: +; DWARFCFI-NEXT: paciasp +; DWARFCFI-NEXT: .cfi_negate_ra_state +; DWARFCFI-NEXT: str x30, [x18], #8 +; DWARFCFI-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 // +; DWARFCFI-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-NEXT: .cfi_offset w30, -16 +; DWARFCFI-NEXT: bl foo +; DWARFCFI-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-NEXT: ldr x30, [x18, #-8]! +; DWARFCFI-NEXT: autiasp +; DWARFCFI-NEXT: ret +; +; WINCFI-LABEL: non_leaf_scs: +; WINCFI: .seh_proc non_leaf_scs +; WINCFI-NEXT: // %bb.0: +; WINCFI-NEXT: pacibsp +; WINCFI-NEXT: .seh_pac_sign_lr +; WINCFI-NEXT: str x30, [x18], #8 +; WINCFI-NEXT: .seh_nop +; WINCFI-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-NEXT: .seh_endprologue +; WINCFI-NEXT: bl foo +; WINCFI-NEXT: .seh_startepilogue +; WINCFI-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-NEXT: ldr x30, [x18, #-8]! +; WINCFI-NEXT: .seh_nop +; WINCFI-NEXT: autibsp +; WINCFI-NEXT: .seh_pac_sign_lr +; WINCFI-NEXT: .seh_endepilogue +; WINCFI-NEXT: ret +; WINCFI-NEXT: .seh_endfunclet +; WINCFI-NEXT: .seh_endproc %call = call i32 @foo(i32 %x) ret i32 %call } @@ -153,47 +331,97 @@ define i32 @non_leaf_scs(i32 %x) "sign-return-address"="non-leaf" shadowcallstac ; By default, pac-ret hardening respects shrink-wrapping optimization. define void @shrink_wrap_sign_non_leaf(i32 %x, i32 %cond) "sign-return-address"="non-leaf" uwtable(async) { -; COMPAT-LABEL: shrink_wrap_sign_non_leaf: -; COMPAT: // %bb.0: // %entry -; COMPAT-NEXT: cbnz w1, .LBB8_2 -; COMPAT-NEXT: // %bb.1: // %if.then -; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_def_cfa_offset 16 -; COMPAT-NEXT: .cfi_offset w30, -16 -; COMPAT-NEXT: bl foo -; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: .cfi_def_cfa_offset 0 -; COMPAT-NEXT: .cfi_restore w30 -; COMPAT-NEXT: hint #29 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: .LBB8_2: // %exit -; COMPAT-NEXT: adrp x8, var -; COMPAT-NEXT: mov w9, #42 // =0x2a -; COMPAT-NEXT: str x9, [x8, :lo12:var] -; COMPAT-NEXT: ret -; -; V83A-LABEL: shrink_wrap_sign_non_leaf: -; V83A: // %bb.0: // %entry -; V83A-NEXT: cbnz w1, .LBB8_2 -; V83A-NEXT: // %bb.1: // %if.then -; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_def_cfa_offset 16 -; V83A-NEXT: .cfi_offset w30, -16 -; V83A-NEXT: bl foo -; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: .cfi_def_cfa_offset 0 -; V83A-NEXT: .cfi_restore w30 -; V83A-NEXT: autiasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: .LBB8_2: // %exit -; V83A-NEXT: adrp x8, var -; V83A-NEXT: mov w9, #42 // =0x2a -; V83A-NEXT: str x9, [x8, :lo12:var] -; V83A-NEXT: ret +; DWARFCFI-COMPAT-LABEL: shrink_wrap_sign_non_leaf: +; DWARFCFI-COMPAT: // %bb.0: // %entry +; DWARFCFI-COMPAT-NEXT: cbnz w1, .LBB8_2 +; DWARFCFI-COMPAT-NEXT: // %bb.1: // %if.then +; DWARFCFI-COMPAT-NEXT: hint #25 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-COMPAT-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-COMPAT-NEXT: .cfi_offset w30, -16 +; DWARFCFI-COMPAT-NEXT: bl foo +; DWARFCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-COMPAT-NEXT: .cfi_def_cfa_offset 0 +; DWARFCFI-COMPAT-NEXT: .cfi_restore w30 +; DWARFCFI-COMPAT-NEXT: hint #29 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: .LBB8_2: // %exit +; DWARFCFI-COMPAT-NEXT: adrp x8, var +; DWARFCFI-COMPAT-NEXT: mov w9, #42 // =0x2a +; DWARFCFI-COMPAT-NEXT: str x9, [x8, :lo12:var] +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: shrink_wrap_sign_non_leaf: +; DWARFCFI-V83A: // %bb.0: // %entry +; DWARFCFI-V83A-NEXT: cbnz w1, .LBB8_2 +; DWARFCFI-V83A-NEXT: // %bb.1: // %if.then +; DWARFCFI-V83A-NEXT: paciasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-V83A-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-V83A-NEXT: .cfi_offset w30, -16 +; DWARFCFI-V83A-NEXT: bl foo +; DWARFCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-V83A-NEXT: .cfi_def_cfa_offset 0 +; DWARFCFI-V83A-NEXT: .cfi_restore w30 +; DWARFCFI-V83A-NEXT: autiasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: .LBB8_2: // %exit +; DWARFCFI-V83A-NEXT: adrp x8, var +; DWARFCFI-V83A-NEXT: mov w9, #42 // =0x2a +; DWARFCFI-V83A-NEXT: str x9, [x8, :lo12:var] +; DWARFCFI-V83A-NEXT: ret +; +; WINCFI-COMPAT-LABEL: shrink_wrap_sign_non_leaf: +; WINCFI-COMPAT: .seh_proc shrink_wrap_sign_non_leaf +; WINCFI-COMPAT-NEXT: // %bb.0: // %entry +; WINCFI-COMPAT-NEXT: hint #27 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: cbnz w1, .LBB8_2 +; WINCFI-COMPAT-NEXT: // %bb.1: // %if.then +; WINCFI-COMPAT-NEXT: bl foo +; WINCFI-COMPAT-NEXT: .LBB8_2: // %exit +; WINCFI-COMPAT-NEXT: adrp x8, var +; WINCFI-COMPAT-NEXT: mov w9, #42 // =0x2a +; WINCFI-COMPAT-NEXT: str x9, [x8, :lo12:var] +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: hint #31 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: shrink_wrap_sign_non_leaf: +; WINCFI-V83A: .seh_proc shrink_wrap_sign_non_leaf +; WINCFI-V83A-NEXT: // %bb.0: // %entry +; WINCFI-V83A-NEXT: pacibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: cbnz w1, .LBB8_2 +; WINCFI-V83A-NEXT: // %bb.1: // %if.then +; WINCFI-V83A-NEXT: bl foo +; WINCFI-V83A-NEXT: .LBB8_2: // %exit +; WINCFI-V83A-NEXT: adrp x8, var +; WINCFI-V83A-NEXT: mov w9, #42 // =0x2a +; WINCFI-V83A-NEXT: str x9, [x8, :lo12:var] +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: autibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc entry: %cond.bool = icmp eq i32 %cond, 0 br i1 %cond.bool, label %if.then, label %exit @@ -208,45 +436,95 @@ exit: ; When "+leaf" is specified to harden everything, pac-ret hardens the entire ; function, ignoring shrink-wrapping. define void @shrink_wrap_sign_all(i32 %x, i32 %cond) "sign-return-address"="all" uwtable(async) { -; COMPAT-LABEL: shrink_wrap_sign_all: -; COMPAT: // %bb.0: // %entry -; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: cbnz w1, .LBB9_2 -; COMPAT-NEXT: // %bb.1: // %if.then -; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_def_cfa_offset 16 -; COMPAT-NEXT: .cfi_offset w30, -16 -; COMPAT-NEXT: bl foo -; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: .cfi_def_cfa_offset 0 -; COMPAT-NEXT: .cfi_restore w30 -; COMPAT-NEXT: .LBB9_2: // %exit -; COMPAT-NEXT: adrp x8, var -; COMPAT-NEXT: mov w9, #42 // =0x2a -; COMPAT-NEXT: str x9, [x8, :lo12:var] -; COMPAT-NEXT: hint #29 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: ret -; -; V83A-LABEL: shrink_wrap_sign_all: -; V83A: // %bb.0: // %entry -; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: cbnz w1, .LBB9_2 -; V83A-NEXT: // %bb.1: // %if.then -; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_def_cfa_offset 16 -; V83A-NEXT: .cfi_offset w30, -16 -; V83A-NEXT: bl foo -; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: .cfi_def_cfa_offset 0 -; V83A-NEXT: .cfi_restore w30 -; V83A-NEXT: .LBB9_2: // %exit -; V83A-NEXT: adrp x8, var -; V83A-NEXT: mov w9, #42 // =0x2a -; V83A-NEXT: str x9, [x8, :lo12:var] -; V83A-NEXT: retaa +; DWARFCFI-COMPAT-LABEL: shrink_wrap_sign_all: +; DWARFCFI-COMPAT: // %bb.0: // %entry +; DWARFCFI-COMPAT-NEXT: hint #25 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: cbnz w1, .LBB9_2 +; DWARFCFI-COMPAT-NEXT: // %bb.1: // %if.then +; DWARFCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-COMPAT-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-COMPAT-NEXT: .cfi_offset w30, -16 +; DWARFCFI-COMPAT-NEXT: bl foo +; DWARFCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-COMPAT-NEXT: .cfi_def_cfa_offset 0 +; DWARFCFI-COMPAT-NEXT: .cfi_restore w30 +; DWARFCFI-COMPAT-NEXT: .LBB9_2: // %exit +; DWARFCFI-COMPAT-NEXT: adrp x8, var +; DWARFCFI-COMPAT-NEXT: mov w9, #42 // =0x2a +; DWARFCFI-COMPAT-NEXT: str x9, [x8, :lo12:var] +; DWARFCFI-COMPAT-NEXT: hint #29 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: shrink_wrap_sign_all: +; DWARFCFI-V83A: // %bb.0: // %entry +; DWARFCFI-V83A-NEXT: paciasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: cbnz w1, .LBB9_2 +; DWARFCFI-V83A-NEXT: // %bb.1: // %if.then +; DWARFCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-V83A-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-V83A-NEXT: .cfi_offset w30, -16 +; DWARFCFI-V83A-NEXT: bl foo +; DWARFCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-V83A-NEXT: .cfi_def_cfa_offset 0 +; DWARFCFI-V83A-NEXT: .cfi_restore w30 +; DWARFCFI-V83A-NEXT: .LBB9_2: // %exit +; DWARFCFI-V83A-NEXT: adrp x8, var +; DWARFCFI-V83A-NEXT: mov w9, #42 // =0x2a +; DWARFCFI-V83A-NEXT: str x9, [x8, :lo12:var] +; DWARFCFI-V83A-NEXT: retaa +; +; WINCFI-COMPAT-LABEL: shrink_wrap_sign_all: +; WINCFI-COMPAT: .seh_proc shrink_wrap_sign_all +; WINCFI-COMPAT-NEXT: // %bb.0: // %entry +; WINCFI-COMPAT-NEXT: hint #27 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: cbnz w1, .LBB9_2 +; WINCFI-COMPAT-NEXT: // %bb.1: // %if.then +; WINCFI-COMPAT-NEXT: bl foo +; WINCFI-COMPAT-NEXT: .LBB9_2: // %exit +; WINCFI-COMPAT-NEXT: adrp x8, var +; WINCFI-COMPAT-NEXT: mov w9, #42 // =0x2a +; WINCFI-COMPAT-NEXT: str x9, [x8, :lo12:var] +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: hint #31 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: shrink_wrap_sign_all: +; WINCFI-V83A: .seh_proc shrink_wrap_sign_all +; WINCFI-V83A-NEXT: // %bb.0: // %entry +; WINCFI-V83A-NEXT: pacibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: cbnz w1, .LBB9_2 +; WINCFI-V83A-NEXT: // %bb.1: // %if.then +; WINCFI-V83A-NEXT: bl foo +; WINCFI-V83A-NEXT: .LBB9_2: // %exit +; WINCFI-V83A-NEXT: adrp x8, var +; WINCFI-V83A-NEXT: mov w9, #42 // =0x2a +; WINCFI-V83A-NEXT: str x9, [x8, :lo12:var] +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: autibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc entry: %cond.bool = icmp eq i32 %cond, 0 br i1 %cond.bool, label %if.then, label %exit @@ -259,136 +537,332 @@ exit: } define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" { -; CHECK-LABEL: leaf_sign_all_v83: -; CHECK: // %bb.0: -; CHECK-NEXT: paciasp -; CHECK-NEXT: .cfi_negate_ra_state -; CHECK-NEXT: retaa +; DWARFCFI-LABEL: leaf_sign_all_v83: +; DWARFCFI: // %bb.0: +; DWARFCFI-NEXT: paciasp +; DWARFCFI-NEXT: .cfi_negate_ra_state +; DWARFCFI-NEXT: retaa +; +; WINCFI-LABEL: leaf_sign_all_v83: +; WINCFI: .seh_proc leaf_sign_all_v83 +; WINCFI-NEXT: // %bb.0: +; WINCFI-NEXT: pacibsp +; WINCFI-NEXT: .seh_pac_sign_lr +; WINCFI-NEXT: .seh_endprologue +; WINCFI-NEXT: .seh_startepilogue +; WINCFI-NEXT: autibsp +; WINCFI-NEXT: .seh_pac_sign_lr +; WINCFI-NEXT: .seh_endepilogue +; WINCFI-NEXT: ret +; WINCFI-NEXT: .seh_endfunclet +; WINCFI-NEXT: .seh_endproc ret i32 %x } declare fastcc i64 @bar(i64) define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" { -; COMPAT-LABEL: spill_lr_and_tail_call: -; COMPAT: // %bb.0: -; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_def_cfa_offset 16 -; COMPAT-NEXT: .cfi_offset w30, -16 -; COMPAT-NEXT: //APP -; COMPAT-NEXT: mov x30, x0 -; COMPAT-NEXT: //NO_APP -; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: hint #29 -; COMPAT-NEXT: b bar -; -; V83A-LABEL: spill_lr_and_tail_call: -; V83A: // %bb.0: -; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_def_cfa_offset 16 -; V83A-NEXT: .cfi_offset w30, -16 -; V83A-NEXT: //APP -; V83A-NEXT: mov x30, x0 -; V83A-NEXT: //NO_APP -; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: autiasp -; V83A-NEXT: b bar +; DWARFCFI-COMPAT-LABEL: spill_lr_and_tail_call: +; DWARFCFI-COMPAT: // %bb.0: +; DWARFCFI-COMPAT-NEXT: hint #25 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-COMPAT-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-COMPAT-NEXT: .cfi_offset w30, -16 +; DWARFCFI-COMPAT-NEXT: //APP +; DWARFCFI-COMPAT-NEXT: mov x30, x0 +; DWARFCFI-COMPAT-NEXT: //NO_APP +; DWARFCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-COMPAT-NEXT: hint #29 +; DWARFCFI-COMPAT-NEXT: b bar +; +; DWARFCFI-V83A-LABEL: spill_lr_and_tail_call: +; DWARFCFI-V83A: // %bb.0: +; DWARFCFI-V83A-NEXT: paciasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; DWARFCFI-V83A-NEXT: .cfi_def_cfa_offset 16 +; DWARFCFI-V83A-NEXT: .cfi_offset w30, -16 +; DWARFCFI-V83A-NEXT: //APP +; DWARFCFI-V83A-NEXT: mov x30, x0 +; DWARFCFI-V83A-NEXT: //NO_APP +; DWARFCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; DWARFCFI-V83A-NEXT: autiasp +; DWARFCFI-V83A-NEXT: b bar +; +; WINCFI-COMPAT-LABEL: spill_lr_and_tail_call: +; WINCFI-COMPAT: .seh_proc spill_lr_and_tail_call +; WINCFI-COMPAT-NEXT: // %bb.0: +; WINCFI-COMPAT-NEXT: hint #27 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: //APP +; WINCFI-COMPAT-NEXT: mov x30, x0 +; WINCFI-COMPAT-NEXT: //NO_APP +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-COMPAT-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-COMPAT-NEXT: hint #31 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: b bar +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: spill_lr_and_tail_call: +; WINCFI-V83A: .seh_proc spill_lr_and_tail_call +; WINCFI-V83A-NEXT: // %bb.0: +; WINCFI-V83A-NEXT: pacibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: //APP +; WINCFI-V83A-NEXT: mov x30, x0 +; WINCFI-V83A-NEXT: //NO_APP +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; WINCFI-V83A-NEXT: .seh_save_reg_x x30, 16 +; WINCFI-V83A-NEXT: autibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: b bar +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1 tail call fastcc i64 @bar(i64 %x) ret void } define i32 @leaf_sign_all_a_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" { -; COMPAT-LABEL: leaf_sign_all_a_key: -; COMPAT: // %bb.0: -; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: hint #29 -; COMPAT-NEXT: ret -; -; V83A-LABEL: leaf_sign_all_a_key: -; V83A: // %bb.0: -; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: retaa +; DWARFCFI-COMPAT-LABEL: leaf_sign_all_a_key: +; DWARFCFI-COMPAT: // %bb.0: +; DWARFCFI-COMPAT-NEXT: hint #25 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: hint #29 +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: leaf_sign_all_a_key: +; DWARFCFI-V83A: // %bb.0: +; DWARFCFI-V83A-NEXT: paciasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: retaa +; +; WINCFI-COMPAT-LABEL: leaf_sign_all_a_key: +; WINCFI-COMPAT: .seh_proc leaf_sign_all_a_key +; WINCFI-COMPAT-NEXT: // %bb.0: +; WINCFI-COMPAT-NEXT: hint #25 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: hint #29 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: leaf_sign_all_a_key: +; WINCFI-V83A: .seh_proc leaf_sign_all_a_key +; WINCFI-V83A-NEXT: // %bb.0: +; WINCFI-V83A-NEXT: paciasp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: autiasp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc ret i32 %x } define i32 @leaf_sign_all_b_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" { -; COMPAT-LABEL: leaf_sign_all_b_key: -; COMPAT: // %bb.0: -; COMPAT-NEXT: .cfi_b_key_frame -; COMPAT-NEXT: hint #27 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: hint #31 -; COMPAT-NEXT: ret -; -; V83A-LABEL: leaf_sign_all_b_key: -; V83A: // %bb.0: -; V83A-NEXT: .cfi_b_key_frame -; V83A-NEXT: pacibsp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: retab +; DWARFCFI-COMPAT-LABEL: leaf_sign_all_b_key: +; DWARFCFI-COMPAT: // %bb.0: +; DWARFCFI-COMPAT-NEXT: .cfi_b_key_frame +; DWARFCFI-COMPAT-NEXT: hint #27 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: hint #31 +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: leaf_sign_all_b_key: +; DWARFCFI-V83A: // %bb.0: +; DWARFCFI-V83A-NEXT: .cfi_b_key_frame +; DWARFCFI-V83A-NEXT: pacibsp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: retab +; +; WINCFI-COMPAT-LABEL: leaf_sign_all_b_key: +; WINCFI-COMPAT: .seh_proc leaf_sign_all_b_key +; WINCFI-COMPAT-NEXT: // %bb.0: +; WINCFI-COMPAT-NEXT: hint #27 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: hint #31 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: leaf_sign_all_b_key: +; WINCFI-V83A: .seh_proc leaf_sign_all_b_key +; WINCFI-V83A-NEXT: // %bb.0: +; WINCFI-V83A-NEXT: pacibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: autibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc ret i32 %x } define i32 @leaf_sign_all_v83_b_key(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" { -; CHECK-LABEL: leaf_sign_all_v83_b_key: -; CHECK: // %bb.0: -; CHECK-NEXT: .cfi_b_key_frame -; CHECK-NEXT: pacibsp -; CHECK-NEXT: .cfi_negate_ra_state -; CHECK-NEXT: retab +; DWARFCFI-LABEL: leaf_sign_all_v83_b_key: +; DWARFCFI: // %bb.0: +; DWARFCFI-NEXT: .cfi_b_key_frame +; DWARFCFI-NEXT: pacibsp +; DWARFCFI-NEXT: .cfi_negate_ra_state +; DWARFCFI-NEXT: retab +; +; WINCFI-LABEL: leaf_sign_all_v83_b_key: +; WINCFI: .seh_proc leaf_sign_all_v83_b_key +; WINCFI-NEXT: // %bb.0: +; WINCFI-NEXT: pacibsp +; WINCFI-NEXT: .seh_pac_sign_lr +; WINCFI-NEXT: .seh_endprologue +; WINCFI-NEXT: .seh_startepilogue +; WINCFI-NEXT: autibsp +; WINCFI-NEXT: .seh_pac_sign_lr +; WINCFI-NEXT: .seh_endepilogue +; WINCFI-NEXT: ret +; WINCFI-NEXT: .seh_endfunclet +; WINCFI-NEXT: .seh_endproc ret i32 %x } ; Note that BTI instruction is not needed before PACIASP. define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" "branch-target-enforcement"{ -; COMPAT-LABEL: leaf_sign_all_a_key_bti: -; COMPAT: // %bb.0: -; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: hint #29 -; COMPAT-NEXT: ret -; -; V83A-LABEL: leaf_sign_all_a_key_bti: -; V83A: // %bb.0: -; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: retaa +; DWARFCFI-COMPAT-LABEL: leaf_sign_all_a_key_bti: +; DWARFCFI-COMPAT: // %bb.0: +; DWARFCFI-COMPAT-NEXT: hint #25 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: hint #29 +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: leaf_sign_all_a_key_bti: +; DWARFCFI-V83A: // %bb.0: +; DWARFCFI-V83A-NEXT: paciasp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: retaa +; +; WINCFI-COMPAT-LABEL: leaf_sign_all_a_key_bti: +; WINCFI-COMPAT: .seh_proc leaf_sign_all_a_key_bti +; WINCFI-COMPAT-NEXT: // %bb.0: +; WINCFI-COMPAT-NEXT: hint #25 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: hint #29 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: leaf_sign_all_a_key_bti: +; WINCFI-V83A: .seh_proc leaf_sign_all_a_key_bti +; WINCFI-V83A-NEXT: // %bb.0: +; WINCFI-V83A-NEXT: paciasp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: autiasp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc ret i32 %x } ; Note that BTI instruction is not needed before PACIBSP. define i32 @leaf_sign_all_b_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" "branch-target-enforcement"{ -; COMPAT-LABEL: leaf_sign_all_b_key_bti: -; COMPAT: // %bb.0: -; COMPAT-NEXT: .cfi_b_key_frame -; COMPAT-NEXT: hint #27 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: hint #31 -; COMPAT-NEXT: ret -; -; V83A-LABEL: leaf_sign_all_b_key_bti: -; V83A: // %bb.0: -; V83A-NEXT: .cfi_b_key_frame -; V83A-NEXT: pacibsp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: retab +; DWARFCFI-COMPAT-LABEL: leaf_sign_all_b_key_bti: +; DWARFCFI-COMPAT: // %bb.0: +; DWARFCFI-COMPAT-NEXT: .cfi_b_key_frame +; DWARFCFI-COMPAT-NEXT: hint #27 +; DWARFCFI-COMPAT-NEXT: .cfi_negate_ra_state +; DWARFCFI-COMPAT-NEXT: hint #31 +; DWARFCFI-COMPAT-NEXT: ret +; +; DWARFCFI-V83A-LABEL: leaf_sign_all_b_key_bti: +; DWARFCFI-V83A: // %bb.0: +; DWARFCFI-V83A-NEXT: .cfi_b_key_frame +; DWARFCFI-V83A-NEXT: pacibsp +; DWARFCFI-V83A-NEXT: .cfi_negate_ra_state +; DWARFCFI-V83A-NEXT: retab +; +; WINCFI-COMPAT-LABEL: leaf_sign_all_b_key_bti: +; WINCFI-COMPAT: .seh_proc leaf_sign_all_b_key_bti +; WINCFI-COMPAT-NEXT: // %bb.0: +; WINCFI-COMPAT-NEXT: hint #27 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endprologue +; WINCFI-COMPAT-NEXT: .seh_startepilogue +; WINCFI-COMPAT-NEXT: hint #31 +; WINCFI-COMPAT-NEXT: .seh_pac_sign_lr +; WINCFI-COMPAT-NEXT: .seh_endepilogue +; WINCFI-COMPAT-NEXT: ret +; WINCFI-COMPAT-NEXT: .seh_endfunclet +; WINCFI-COMPAT-NEXT: .seh_endproc +; +; WINCFI-V83A-LABEL: leaf_sign_all_b_key_bti: +; WINCFI-V83A: .seh_proc leaf_sign_all_b_key_bti +; WINCFI-V83A-NEXT: // %bb.0: +; WINCFI-V83A-NEXT: pacibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endprologue +; WINCFI-V83A-NEXT: .seh_startepilogue +; WINCFI-V83A-NEXT: autibsp +; WINCFI-V83A-NEXT: .seh_pac_sign_lr +; WINCFI-V83A-NEXT: .seh_endepilogue +; WINCFI-V83A-NEXT: ret +; WINCFI-V83A-NEXT: .seh_endfunclet +; WINCFI-V83A-NEXT: .seh_endproc ret i32 %x } ; Note that BTI instruction is not needed before PACIBSP. define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" "branch-target-enforcement" { -; CHECK-LABEL: leaf_sign_all_v83_b_key_bti: -; CHECK: // %bb.0: -; CHECK-NEXT: .cfi_b_key_frame -; CHECK-NEXT: pacibsp -; CHECK-NEXT: .cfi_negate_ra_state -; CHECK-NEXT: retab +; DWARFCFI-LABEL: leaf_sign_all_v83_b_key_bti: +; DWARFCFI: // %bb.0: +; DWARFCFI-NEXT: .cfi_b_key_frame +; DWARFCFI-NEXT: pacibsp +; DWARFCFI-NEXT: .cfi_negate_ra_state +; DWARFCFI-NEXT: retab +; +; WINCFI-LABEL: leaf_sign_all_v83_b_key_bti: +; WINCFI: .seh_proc leaf_sign_all_v83_b_key_bti +; WINCFI-NEXT: // %bb.0: +; WINCFI-NEXT: pacibsp +; WINCFI-NEXT: .seh_pac_sign_lr +; WINCFI-NEXT: .seh_endprologue +; WINCFI-NEXT: .seh_startepilogue +; WINCFI-NEXT: autibsp +; WINCFI-NEXT: .seh_pac_sign_lr +; WINCFI-NEXT: .seh_endepilogue +; WINCFI-NEXT: ret +; WINCFI-NEXT: .seh_endfunclet +; WINCFI-NEXT: .seh_endproc ret i32 %x }