diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h --- a/llvm/lib/Target/AArch64/AArch64.h +++ b/llvm/lib/Target/AArch64/AArch64.h @@ -51,6 +51,7 @@ FunctionPass *createAArch64A53Fix835769(); FunctionPass *createFalkorHWPFFixPass(); FunctionPass *createFalkorMarkStridedAccessesPass(); +FunctionPass *createAArch64PointerAuthPass(); FunctionPass *createAArch64BranchTargetsPass(); FunctionPass *createAArch64MIPeepholeOptPass(); @@ -74,6 +75,7 @@ void initializeAArch64A53Fix835769Pass(PassRegistry&); void initializeAArch64A57FPLoadBalancingPass(PassRegistry&); void initializeAArch64AdvSIMDScalarPass(PassRegistry&); +void initializeAArch64PointerAuthPass(PassRegistry&); void initializeAArch64BranchTargetsPass(PassRegistry&); void initializeAArch64CFIFixupPass(PassRegistry&); void initializeAArch64CollectLOHPass(PassRegistry &); diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.h @@ -30,13 +30,6 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override; - static void signLR(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, bool NeedsWinCFI, - bool *HasWinCFI); - - static void authenticateLR(MachineFunction &MF, MachineBasicBlock &MBB, - bool NeedsWinCFI, bool *HasWinCFI); - /// emitProlog/emitEpilog - These methods insert prolog and epilog code into /// the function. void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1386,42 +1386,6 @@ .setMIFlags(MachineInstr::FrameSetup); } -void AArch64FrameLowering::signLR(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - bool NeedsWinCFI, bool *HasWinCFI) { - const auto &MFnI = *MF.getInfo(); - const AArch64Subtarget &Subtarget = MF.getSubtarget(); - const TargetInstrInfo *TII = Subtarget.getInstrInfo(); - bool EmitCFI = MFnI.needsDwarfUnwindInfo(MF); - - // Debug location must be unknown, see emitPrologue(). - DebugLoc DL; - - if (MFnI.shouldSignWithBKey()) { - BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITBKEY)) - .setMIFlag(MachineInstr::FrameSetup); - } - - // No SEH opcode for this one; it doesn't materialize into an - // instruction on Windows. - BuildMI( - MBB, MBBI, DL, - TII->get(MFnI.shouldSignWithBKey() ? AArch64::PACIBSP : AArch64::PACIASP)) - .setMIFlag(MachineInstr::FrameSetup); - - if (EmitCFI) { - unsigned CFIIndex = - MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameSetup); - } else if (NeedsWinCFI) { - *HasWinCFI = true; - BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR)) - .setMIFlag(MachineInstr::FrameSetup); - } -} - void AArch64FrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.begin(); @@ -1455,8 +1419,12 @@ emitShadowCallStackPrologue(*TII, MF, MBB, MBBI, DL, NeedsWinCFI, MFnI.needsDwarfUnwindInfo(MF)); - if (MFnI.shouldSignReturnAddress(MF)) - signLR(MF, MBB, MBBI, NeedsWinCFI, &HasWinCFI); + if (MFnI.shouldSignReturnAddress(MF)) { + BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE)) + .setMIFlag(MachineInstr::FrameSetup); + if (NeedsWinCFI) + HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR + } if (EmitCFI && MFnI.isMTETagged()) { BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITMTETAGGED)) @@ -1916,54 +1884,6 @@ } } -void AArch64FrameLowering::authenticateLR(MachineFunction &MF, - MachineBasicBlock &MBB, - bool NeedsWinCFI, bool *HasWinCFI) { - const auto &MFI = *MF.getInfo(); - const AArch64Subtarget &Subtarget = MF.getSubtarget(); - const TargetInstrInfo *TII = Subtarget.getInstrInfo(); - bool EmitAsyncCFI = MFI.needsAsyncDwarfUnwindInfo(MF); - - MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); - DebugLoc DL; - if (MBBI != MBB.end()) - DL = MBBI->getDebugLoc(); - - // The AUTIASP instruction assembles to a hint instruction before v8.3a so - // this instruction can safely used for any v8a architecture. - // From v8.3a onwards there are optimised authenticate LR and return - // instructions, namely RETA{A,B}, that can be used instead. In this case the - // DW_CFA_AARCH64_negate_ra_state can't be emitted. - bool TerminatorIsCombinable = - MBBI != MBB.end() && (MBBI->getOpcode() == AArch64::RET_ReallyLR || - MBBI->getOpcode() == AArch64::RET); - if (Subtarget.hasPAuth() && TerminatorIsCombinable && !NeedsWinCFI && - !MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack)) { - BuildMI(MBB, MBBI, DL, - TII->get(MFI.shouldSignWithBKey() ? AArch64::RETAB : AArch64::RETAA)) - .copyImplicitOps(*MBBI); - MBB.erase(MBBI); - } else { - BuildMI( - MBB, MBBI, DL, - TII->get(MFI.shouldSignWithBKey() ? AArch64::AUTIBSP : AArch64::AUTIASP)) - .setMIFlag(MachineInstr::FrameDestroy); - - if (EmitAsyncCFI) { - unsigned CFIIndex = - MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameDestroy); - } - if (NeedsWinCFI) { - *HasWinCFI = true; - BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR)) - .setMIFlag(MachineInstr::FrameDestroy); - } - } -} - static bool isFuncletReturnInstr(const MachineInstr &MI) { switch (MI.getOpcode()) { default: @@ -1995,8 +1915,13 @@ MachineBasicBlock::iterator EpilogStartI = MBB.end(); auto FinishingTouches = make_scope_exit([&]() { - if (AFI->shouldSignReturnAddress(MF)) - authenticateLR(MF, MBB, NeedsWinCFI, &HasWinCFI); + if (AFI->shouldSignReturnAddress(MF)) { + BuildMI(MBB, MBB.getFirstTerminator(), DL, + TII->get(AArch64::PAUTH_EPILOGUE)) + .setMIFlag(MachineInstr::FrameDestroy); + if (NeedsWinCFI) + HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR + } if (needsShadowCallStackPrologueEpilogue(MF)) emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL); if (EmitCFI) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -7957,6 +7957,8 @@ case AArch64::RETAA: case AArch64::RETAB: case AArch64::EMITBKEY: + case AArch64::PAUTH_PROLOGUE: + case AArch64::PAUTH_EPILOGUE: return outliner::InstrType::Illegal; } @@ -8108,15 +8110,16 @@ } static void signOutlinedFunction(MachineFunction &MF, MachineBasicBlock &MBB, + const AArch64InstrInfo *TII, bool ShouldSignReturnAddr) { if (!ShouldSignReturnAddr) return; - AArch64FrameLowering::signLR(MF, MBB, MBB.begin(), - /*NeedsWinCFI=*/false, /*HasWinCFI=*/nullptr); - - AArch64FrameLowering::authenticateLR(MF, MBB, /*NeedsWinCFI=*/false, - /*HasWinCFI=*/nullptr); + BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(AArch64::PAUTH_PROLOGUE)) + .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBB.getFirstInstrTerminator(), DebugLoc(), + TII->get(AArch64::PAUTH_EPILOGUE)) + .setMIFlag(MachineInstr::FrameDestroy); } void AArch64InstrInfo::buildOutlinedFrame( @@ -8221,7 +8224,7 @@ // If this is a tail call outlined function, then there's already a return. if (OF.FrameConstructionID == MachineOutlinerTailCall || OF.FrameConstructionID == MachineOutlinerThunk) { - signOutlinedFunction(MF, MBB, ShouldSignReturnAddr); + signOutlinedFunction(MF, MBB, this, ShouldSignReturnAddr); return; } @@ -8235,7 +8238,7 @@ .addReg(AArch64::LR); MBB.insert(MBB.end(), ret); - signOutlinedFunction(MF, MBB, ShouldSignReturnAddr); + signOutlinedFunction(MF, MBB, this, ShouldSignReturnAddr); FI->setOutliningStyle("Function"); diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -1477,6 +1477,15 @@ def : InstAlias<"autib1716", (AUTIB1716), 0>; def : InstAlias<"xpaclri", (XPACLRI), 0>; +// Pseudos + +// Insertion point of LR signing code. +def PAUTH_PROLOGUE : Pseudo<(outs), (ins), []>, Sched<[]>; +// Insertion point of LR authentication code. +// The RET terminator of the containing machine basic block may be replaced +// with a combined RETA(A|B) instruction when rewriting this Pseudo. +def PAUTH_EPILOGUE : Pseudo<(outs), (ins), []>, Sched<[]>; + // These pointer authentication instructions require armv8.3a let Predicates = [HasPAuth] in { diff --git a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp @@ -0,0 +1,170 @@ +//===-- AArch64PointerAuth.cpp -- Harden code using PAuth ------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "AArch64.h" +#include "AArch64MachineFunctionInfo.h" +#include "AArch64Subtarget.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" + +using namespace llvm; + +#define AARCH64_POINTER_AUTH_NAME "AArch64 Pointer Authentication" + +namespace { + +class AArch64PointerAuth : public MachineFunctionPass { +public: + static char ID; + + AArch64PointerAuth() : MachineFunctionPass(ID) {} + + bool runOnMachineFunction(MachineFunction &MF) override; + + StringRef getPassName() const override { return AARCH64_POINTER_AUTH_NAME; } + +private: + const AArch64Subtarget *Subtarget = nullptr; + const AArch64InstrInfo *TII = nullptr; + + void signLR(MachineFunction &MF, MachineBasicBlock::iterator MBBI) const; + + void authenticateLR(MachineFunction &MF, + MachineBasicBlock::iterator MBBI) const; +}; + +} // end anonymous namespace + +INITIALIZE_PASS(AArch64PointerAuth, "aarch64-ptrauth", + AARCH64_POINTER_AUTH_NAME, false, false) + +FunctionPass *llvm::createAArch64PointerAuthPass() { + return new AArch64PointerAuth(); +} + +char AArch64PointerAuth::ID = 0; + +void AArch64PointerAuth::signLR(MachineFunction &MF, + MachineBasicBlock::iterator MBBI) const { + const AArch64FunctionInfo *MFnI = MF.getInfo(); + bool UseBKey = MFnI->shouldSignWithBKey(); + bool EmitCFI = MFnI->needsDwarfUnwindInfo(MF); + bool NeedsWinCFI = MF.hasWinCFI(); + + MachineBasicBlock &MBB = *MBBI->getParent(); + + // Debug location must be unknown, see AArch64FrameLowering::emitPrologue. + DebugLoc DL; + + if (UseBKey) { + BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITBKEY)) + .setMIFlag(MachineInstr::FrameSetup); + } + + // No SEH opcode for this one; it doesn't materialize into an + // instruction on Windows. + BuildMI(MBB, MBBI, DL, + TII->get(UseBKey ? AArch64::PACIBSP : AArch64::PACIASP)) + .setMIFlag(MachineInstr::FrameSetup); + + if (EmitCFI) { + unsigned CFIIndex = + MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); + BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlags(MachineInstr::FrameSetup); + } else if (NeedsWinCFI) { + BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR)) + .setMIFlag(MachineInstr::FrameSetup); + } +} + +void AArch64PointerAuth::authenticateLR( + MachineFunction &MF, MachineBasicBlock::iterator MBBI) const { + const AArch64FunctionInfo *MFnI = MF.getInfo(); + bool UseBKey = MFnI->shouldSignWithBKey(); + bool EmitAsyncCFI = MFnI->needsAsyncDwarfUnwindInfo(MF); + bool NeedsWinCFI = MF.hasWinCFI(); + + MachineBasicBlock &MBB = *MBBI->getParent(); + DebugLoc DL = MBBI->getDebugLoc(); + // MBBI points to a PAUTH_EPILOGUE instruction to be replaced and + // TI points to a terminator instruction that may or may not be combined. + // Note that inserting new instructions "before MBBI" and "before TI" is + // not the same because if ShadowCallStack is enabled, its instructions + // are placed between MBBI and TI. + MachineBasicBlock::iterator TI = MBB.getFirstInstrTerminator(); + + // The AUTIASP instruction assembles to a hint instruction before v8.3a so + // this instruction can safely used for any v8a architecture. + // From v8.3a onwards there are optimised authenticate LR and return + // instructions, namely RETA{A,B}, that can be used instead. In this case the + // DW_CFA_AARCH64_negate_ra_state can't be emitted. + bool TerminatorIsCombinable = + TI != MBB.end() && TI->getOpcode() == AArch64::RET; + if (Subtarget->hasPAuth() && TerminatorIsCombinable && !NeedsWinCFI && + !MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack)) { + unsigned CombinedRetOpcode = UseBKey ? AArch64::RETAB : AArch64::RETAA; + BuildMI(MBB, TI, DL, TII->get(CombinedRetOpcode)).copyImplicitOps(*TI); + MBB.erase(TI); + } else { + unsigned AutOpcode = UseBKey ? AArch64::AUTIBSP : AArch64::AUTIASP; + BuildMI(MBB, MBBI, DL, TII->get(AutOpcode)) + .setMIFlag(MachineInstr::FrameDestroy); + + if (EmitAsyncCFI) { + unsigned CFIIndex = + MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); + BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlags(MachineInstr::FrameDestroy); + } + if (NeedsWinCFI) { + BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR)) + .setMIFlag(MachineInstr::FrameDestroy); + } + } +} + +bool AArch64PointerAuth::runOnMachineFunction(MachineFunction &MF) { + if (!MF.getInfo()->shouldSignReturnAddress(true)) + return false; + + Subtarget = &MF.getSubtarget(); + TII = Subtarget->getInstrInfo(); + + SmallVector DeletedInstrs; + bool Modified = false; + + for (auto &MBB : MF) { + for (auto &MI : MBB) { + auto It = MI.getIterator(); + switch (MI.getOpcode()) { + default: + // do nothing + break; + case AArch64::PAUTH_PROLOGUE: + signLR(MF, It); + DeletedInstrs.push_back(It); + Modified = true; + break; + case AArch64::PAUTH_EPILOGUE: + authenticateLR(MF, It); + DeletedInstrs.push_back(It); + Modified = true; + break; + } + } + } + + for (auto MI : DeletedInstrs) + MI->eraseFromParent(); + + return Modified; +} diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -221,6 +221,7 @@ initializeAArch64SIMDInstrOptPass(*PR); initializeAArch64O0PreLegalizerCombinerPass(*PR); initializeAArch64PreLegalizerCombinerPass(*PR); + initializeAArch64PointerAuthPass(*PR); initializeAArch64PostLegalizerCombinerPass(*PR); initializeAArch64PostLegalizerLoweringPass(*PR); initializeAArch64PostSelectOptimizePass(*PR); @@ -811,9 +812,6 @@ addPass(createAArch64A53Fix835769()); - if (EnableBranchTargets) - addPass(createAArch64BranchTargetsPass()); - if (TM->getTargetTriple().isOSWindows()) { // Identify valid longjmp targets for Windows Control Flow Guard. addPass(createCFGuardLongjmpPass()); @@ -827,6 +825,9 @@ } void AArch64PassConfig::addPostBBSections() { + addPass(createAArch64PointerAuthPass()); + if (EnableBranchTargets) + addPass(createAArch64BranchTargetsPass()); // Relax conditional branch instructions if they're otherwise out of // range of their destination. if (BranchRelaxation) diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt --- a/llvm/lib/Target/AArch64/CMakeLists.txt +++ b/llvm/lib/Target/AArch64/CMakeLists.txt @@ -70,6 +70,7 @@ AArch64MacroFusion.cpp AArch64MIPeepholeOpt.cpp AArch64MCInstLower.cpp + AArch64PointerAuth.cpp AArch64PromoteConstant.cpp AArch64PBQPRegAlloc.cpp AArch64RegisterInfo.cpp diff --git a/llvm/test/CodeGen/AArch64/O0-pipeline.ll b/llvm/test/CodeGen/AArch64/O0-pipeline.ll --- a/llvm/test/CodeGen/AArch64/O0-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O0-pipeline.ll @@ -71,11 +71,12 @@ ; CHECK-NEXT: Insert XRay ops ; CHECK-NEXT: Implement the 'patchable-function' attribute ; CHECK-NEXT: Workaround A53 erratum 835769 pass -; CHECK-NEXT: AArch64 Branch Targets ; CHECK-NEXT: Contiguously Lay Out Funclets ; CHECK-NEXT: StackMap Liveness Analysis ; CHECK-NEXT: Live DEBUG_VALUE analysis ; CHECK-NEXT: Machine Sanitizer Binary Metadata +; CHECK-NEXT: AArch64 Pointer Authentication +; CHECK-NEXT: AArch64 Branch Targets ; CHECK-NEXT: Branch relaxation pass ; CHECK-NEXT: Insert CFI remember/restore state instructions ; CHECK-NEXT: Lazy Machine Block Frequency Analysis diff --git a/llvm/test/CodeGen/AArch64/O3-pipeline.ll b/llvm/test/CodeGen/AArch64/O3-pipeline.ll --- a/llvm/test/CodeGen/AArch64/O3-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O3-pipeline.ll @@ -217,13 +217,14 @@ ; CHECK-NEXT: AArch64 load / store optimization pass ; CHECK-NEXT: Machine Copy Propagation Pass ; CHECK-NEXT: Workaround A53 erratum 835769 pass -; CHECK-NEXT: AArch64 Branch Targets ; CHECK-NEXT: Contiguously Lay Out Funclets ; CHECK-NEXT: StackMap Liveness Analysis ; CHECK-NEXT: Live DEBUG_VALUE analysis ; CHECK-NEXT: Machine Sanitizer Binary Metadata ; CHECK-NEXT: Machine Outliner ; CHECK-NEXT: FunctionPass Manager +; CHECK-NEXT: AArch64 Pointer Authentication +; CHECK-NEXT: AArch64 Branch Targets ; CHECK-NEXT: Branch relaxation pass ; CHECK-NEXT: AArch64 Compress Jump Tables ; CHECK-NEXT: Insert CFI remember/restore state instructions diff --git a/llvm/test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll b/llvm/test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll --- a/llvm/test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll +++ b/llvm/test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll @@ -34,6 +34,14 @@ ; HOTNESS-NEXT: Executing Pass 'Function Pass Manager' ; HOTNESS-NEXT: Executing Pass 'Verify generated machine code' ; HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' +; HOTNESS-NEXT: Executing Pass 'AArch64 Pointer Authentication' on Function 'empty_func'... +; HOTNESS-NEXT: Freeing Pass 'AArch64 Pointer Authentication' on Function 'empty_func'... +; HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... +; HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' on Function 'empty_func'... +; HOTNESS-NEXT: Executing Pass 'AArch64 Branch Targets' on Function 'empty_func'... +; HOTNESS-NEXT: Freeing Pass 'AArch64 Branch Targets' on Function 'empty_func'... +; HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... +; HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' on Function 'empty_func'... ; HOTNESS-NEXT: Executing Pass 'Branch relaxation pass' on Function 'empty_func' ; HOTNESS-NEXT: Freeing Pass 'Branch relaxation pass' on Function 'empty_func' ; HOTNESS-NEXT: Executing Pass 'Verify generated machine code' @@ -67,6 +75,14 @@ ; NO_HOTNESS-NEXT: Executing Pass 'Function Pass Manager' ; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code' ; NO_HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' +; NO_HOTNESS-NEXT: Executing Pass 'AArch64 Pointer Authentication' on Function 'empty_func'... +; NO_HOTNESS-NEXT: Freeing Pass 'AArch64 Pointer Authentication' on Function 'empty_func'... +; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... +; NO_HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' on Function 'empty_func'... +; NO_HOTNESS-NEXT: Executing Pass 'AArch64 Branch Targets' on Function 'empty_func'... +; NO_HOTNESS-NEXT: Freeing Pass 'AArch64 Branch Targets' on Function 'empty_func'... +; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code' on Function 'empty_func'... +; NO_HOTNESS-NEXT: Freeing Pass 'Verify generated machine code' on Function 'empty_func'... ; NO_HOTNESS-NEXT: Executing Pass 'Branch relaxation pass' on Function 'empty_func' ; NO_HOTNESS-NEXT: Freeing Pass 'Branch relaxation pass' on Function 'empty_func' ; NO_HOTNESS-NEXT: Executing Pass 'Verify generated machine code' diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir --- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir @@ -1,5 +1,5 @@ -# RUN: llc -mtriple=aarch64 -run-pass=prologepilog \ -# RUN: -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s +# RUN: llc -mtriple=aarch64 -run-pass=prologepilog -run-pass=machine-outliner \ +# RUN: -verify-machineinstrs -run-pass=aarch64-ptrauth %s -o - | FileCheck %s # Check that we save LR to a callee-saved register when possible. # foo() should use a callee-saved register. However, bar() should not. diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir --- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir @@ -1,4 +1,4 @@ -# RUN: llc -verify-machineinstrs -run-pass=machine-outliner %s -o - | FileCheck %s +# RUN: llc -verify-machineinstrs -run-pass=machine-outliner -run-pass=aarch64-ptrauth %s -o - | FileCheck %s --- | target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" @@ -67,8 +67,7 @@ body: | bb.0 (%ir-block.0): liveins: $lr - frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp - frame-setup CFI_INSTRUCTION negate_ra_sign_state + frame-setup PAUTH_PROLOGUE $sp = frame-setup SUBXri $sp, 16, 0 renamable $x8 = ADRP target-flags(aarch64-page) @v $x9 = ADDXri $sp, 12, 0 @@ -80,18 +79,17 @@ STRXui renamable $x9, renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) $sp = frame-destroy ADDXri $sp, 16, 0 - frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp - frame-destroy CFI_INSTRUCTION negate_ra_sign_state + frame-destroy PAUTH_EPILOGUE RET undef $lr # CHECK-LABEL: name: legal0 # CHECK: body: | # CHECK-NEXT: bb.0 (%ir-block.0): # CHECK-NEXT: liveins: $lr -# CHECK: frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK: frame-setup PACIASP implicit-def $lr, implicit $lr, implicit $sp # CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state # CHECK: BL @[[OUTLINED_FUNC:OUTLINED_FUNCTION_[0-9]+]] -# CHECK: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK: frame-destroy AUTIASP implicit-def $lr, implicit $lr, implicit $sp # CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET undef $lr @@ -102,8 +100,7 @@ body: | bb.0 (%ir-block.0): liveins: $lr - frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp - frame-setup CFI_INSTRUCTION negate_ra_sign_state + frame-setup PAUTH_PROLOGUE $sp = frame-setup SUBXri $sp, 16, 0 renamable $x8 = ADRP target-flags(aarch64-page) @v $x9 = ADDXri $sp, 12, 0 @@ -115,18 +112,17 @@ STRXui renamable $x9, renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) $sp = frame-destroy ADDXri $sp, 16, 0 - frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp - frame-destroy CFI_INSTRUCTION negate_ra_sign_state + frame-destroy PAUTH_EPILOGUE RET undef $lr # CHECK-LABEL: name: legal1 # CHECK: body: | # CHECK-NEXT: bb.0 (%ir-block.0): # CHECK-NEXT: liveins: $lr -# CHECK: frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK: frame-setup PACIASP implicit-def $lr, implicit $lr, implicit $sp # CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state # CHECK: BL @[[OUTLINED_FUNC]] -# CHECK: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK: frame-destroy AUTIASP implicit-def $lr, implicit $lr, implicit $sp # CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET undef $lr @@ -137,8 +133,7 @@ body: | bb.0 (%ir-block.0): liveins: $lr - frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp - frame-setup CFI_INSTRUCTION negate_ra_sign_state + frame-setup PAUTH_PROLOGUE $sp = frame-setup SUBXri $sp, 16, 0 renamable $x8 = ADRP target-flags(aarch64-page) @v $x9 = ADDXri $sp, 12, 0 @@ -150,8 +145,7 @@ STRXui renamable $x9, renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) $sp = frame-destroy ADDXri $sp, 12, 0 - frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp - frame-destroy CFI_INSTRUCTION negate_ra_sign_state + frame-destroy PAUTH_EPILOGUE RET undef $lr ... @@ -161,8 +155,7 @@ body: | bb.0 (%ir-block.0): liveins: $lr - frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp - frame-setup CFI_INSTRUCTION negate_ra_sign_state + frame-setup PAUTH_PROLOGUE $sp = frame-setup SUBXri $sp, 16, 0 renamable $x8 = ADRP target-flags(aarch64-page) @v $x9 = ADDXri $sp, 12, 0 @@ -174,18 +167,17 @@ STRXui renamable $x9, renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) STRXui killed renamable $x9, killed renamable $x8, target-flags(aarch64-pageoff, aarch64-nc) @v :: (volatile store (s64) into @v) $sp = frame-destroy ADDXri $sp, 12, 0 - frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp - frame-destroy CFI_INSTRUCTION negate_ra_sign_state + frame-destroy PAUTH_EPILOGUE RET undef $lr # CHECK-LABEL: name: illegal0 # CHECK: body: | # CHECK-NEXT: bb.0 (%ir-block.0): # CHECK-NEXT: liveins: $lr -# CHECK: frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK: frame-setup PACIASP implicit-def $lr, implicit $lr, implicit $sp # CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state # CHECK-NOT: BL @OUTLINED_FUNCTION_{{.*}} -# CHECK: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK: frame-destroy AUTIASP implicit-def $lr, implicit $lr, implicit $sp # CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET undef $lr @@ -193,10 +185,10 @@ # CHECK: body: | # CHECK-NEXT: bb.0 (%ir-block.0): # CHECK-NEXT: liveins: $lr -# CHECK: frame-setup PACIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK: frame-setup PACIASP implicit-def $lr, implicit $lr, implicit $sp # CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state # CHECK-NOT: BL @OUTLINED_FUNCTION_{{.*}} -# CHECK: frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp +# CHECK: frame-destroy AUTIASP implicit-def $lr, implicit $lr, implicit $sp # CHECK-NEXT: frame-destroy CFI_INSTRUCTION negate_ra_sign_state # CHECK-NEXT: RET undef $lr diff --git a/llvm/test/CodeGen/MIR/AArch64/return-address-signing.mir b/llvm/test/CodeGen/MIR/AArch64/return-address-signing.mir --- a/llvm/test/CodeGen/MIR/AArch64/return-address-signing.mir +++ b/llvm/test/CodeGen/MIR/AArch64/return-address-signing.mir @@ -1,4 +1,4 @@ -# RUN: llc -mtriple=aarch64 -run-pass=prologepilog -o - %s 2>&1 | FileCheck %s +# RUN: llc -mtriple=aarch64 -run-pass=prologepilog -run-pass=aarch64-ptrauth -o - %s 2>&1 | FileCheck %s --- | target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64"