[llvm] eb02ee4 - [AArch64] Move PAuth codegen down the machine pipeline

Anatoly Trosinenko via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 22 04:50:23 PDT 2023


Author: Anatoly Trosinenko
Date: 2023-09-22T14:49:14+03:00
New Revision: eb02ee44d32531931af5312cd450779011664eef

URL: https://github.com/llvm/llvm-project/commit/eb02ee44d32531931af5312cd450779011664eef
DIFF: https://github.com/llvm/llvm-project/commit/eb02ee44d32531931af5312cd450779011664eef.diff

LOG: [AArch64] Move PAuth codegen down the machine pipeline

To simplify handling PAuth in the machine outliner, introduce a
separate AArch64PointerAuth pass that is executed after both
Prologue/Epilogue Inserter and Machine Outliner passes.

After moving to AArch64PointerAuth, signLR and authenticateLR are
not used outside of their class anymore, so make them private and
simplify accordingly.

The new pass is added via AArch64PassConfig::addPostBBSections(),
so that it can change the code size before branch relaxation occurs.
AArch64BranchTargets is placed there too, so it can take into account
any PACI(A|B)SP instructions and not excessively add BTIs at the start
of functions.

Reviewed By: tmatheson

Differential Revision: https://reviews.llvm.org/D159357

Added: 
    llvm/lib/Target/AArch64/AArch64PointerAuth.cpp

Modified: 
    llvm/lib/Target/AArch64/AArch64.h
    llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
    llvm/lib/Target/AArch64/AArch64FrameLowering.h
    llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
    llvm/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
    llvm/lib/Target/AArch64/CMakeLists.txt
    llvm/test/CodeGen/AArch64/O0-pipeline.ll
    llvm/test/CodeGen/AArch64/O3-pipeline.ll
    llvm/test/CodeGen/AArch64/arm64-opt-remarks-lazy-bfi.ll
    llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir
    llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir
    llvm/test/CodeGen/MIR/AArch64/return-address-signing.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h
index 1a86fc45adc0720..901769c54b6ef59 100644
--- a/llvm/lib/Target/AArch64/AArch64.h
+++ b/llvm/lib/Target/AArch64/AArch64.h
@@ -51,6 +51,7 @@ FunctionPass *createAArch64A57FPLoadBalancing();
 FunctionPass *createAArch64A53Fix835769();
 FunctionPass *createFalkorHWPFFixPass();
 FunctionPass *createFalkorMarkStridedAccessesPass();
+FunctionPass *createAArch64PointerAuthPass();
 FunctionPass *createAArch64BranchTargetsPass();
 FunctionPass *createAArch64MIPeepholeOptPass();
 
@@ -74,6 +75,7 @@ ModulePass *createAArch64GlobalsTaggingPass();
 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.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 435b095936f6eaf..76df66a3e0fc72b 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -1381,42 +1381,6 @@ static void emitDefineCFAWithFP(MachineFunction &MF, MachineBasicBlock &MBB,
       .setMIFlags(MachineInstr::FrameSetup);
 }
 
-void AArch64FrameLowering::signLR(MachineFunction &MF, MachineBasicBlock &MBB,
-                                  MachineBasicBlock::iterator MBBI,
-                                  bool NeedsWinCFI, bool *HasWinCFI) {
-  const auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
-  const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
-  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();
@@ -1450,8 +1414,12 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
     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))
@@ -1911,54 +1879,6 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
   }
 }
 
-void AArch64FrameLowering::authenticateLR(MachineFunction &MF,
-                                          MachineBasicBlock &MBB,
-                                          bool NeedsWinCFI, bool *HasWinCFI) {
-  const auto &MFI = *MF.getInfo<AArch64FunctionInfo>();
-  const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
-  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:
@@ -1990,8 +1910,13 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
   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/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h
index 2d5529aa2fd8cb9..147b5c181be5e53 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.h
@@ -30,13 +30,6 @@ class AArch64FrameLowering : public TargetFrameLowering {
   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/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index a1e6a8177c10013..c839cd690ce6902 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -7963,6 +7963,8 @@ AArch64InstrInfo::getOutliningTypeImpl(MachineBasicBlock::iterator &MIT,
   case AArch64::RETAA:
   case AArch64::RETAB:
   case AArch64::EMITBKEY:
+  case AArch64::PAUTH_PROLOGUE:
+  case AArch64::PAUTH_EPILOGUE:
     return outliner::InstrType::Illegal;
   }
 
@@ -8114,15 +8116,16 @@ void AArch64InstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const {
 }
 
 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(
@@ -8227,7 +8230,7 @@ void AArch64InstrInfo::buildOutlinedFrame(
   // 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;
   }
 
@@ -8241,7 +8244,7 @@ void AArch64InstrInfo::buildOutlinedFrame(
                           .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
index 8954b563238a269..8350bf71e29e5b4 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1477,6 +1477,15 @@ def : InstAlias<"autia1716", (AUTIA1716), 0>;
 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
index 000000000000000..f8f11b43e35be51
--- /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<AArch64FunctionInfo>();
+  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<AArch64FunctionInfo>();
+  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<AArch64FunctionInfo>()->shouldSignReturnAddress(true))
+    return false;
+
+  Subtarget = &MF.getSubtarget<AArch64Subtarget>();
+  TII = Subtarget->getInstrInfo();
+
+  SmallVector<MachineBasicBlock::iterator> 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
index a3aa4a5a73c3591..2c75a478f52c293 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -221,6 +221,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Target() {
   initializeAArch64SIMDInstrOptPass(*PR);
   initializeAArch64O0PreLegalizerCombinerPass(*PR);
   initializeAArch64PreLegalizerCombinerPass(*PR);
+  initializeAArch64PointerAuthPass(*PR);
   initializeAArch64PostLegalizerCombinerPass(*PR);
   initializeAArch64PostLegalizerLoweringPass(*PR);
   initializeAArch64PostSelectOptimizePass(*PR);
@@ -811,9 +812,6 @@ void AArch64PassConfig::addPreEmitPass() {
 
   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::addPreEmitPass() {
 }
 
 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
index 87b71db2e5ec5a8..d97342b0829d826 100644
--- a/llvm/lib/Target/AArch64/CMakeLists.txt
+++ b/llvm/lib/Target/AArch64/CMakeLists.txt
@@ -70,6 +70,7 @@ add_llvm_target(AArch64CodeGen
   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
index 90a61cc6d928ab0..4f87bb2a3ee811e 100644
--- 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
index fae6b23bf737c30..f5c1c3c291cb585 100644
--- 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
index 9dfe84c46e9f9f1..580886520789e33 100644
--- 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
index 9627557d4e3faca..28986064e794601 100644
--- 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
index 3199b091766c46b..9c115a1de0db162 100644
--- 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 @@ tracksRegLiveness: true
 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 @@ body:             |
     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 @@ tracksRegLiveness: true
 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 @@ body:             |
     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 @@ tracksRegLiveness: true
 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 @@ body:             |
     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 @@ tracksRegLiveness: true
 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 @@ body:             |
     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 @@ body:             |
 # 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
index bbb59de2737f89f..a63bb8452ebbe14 100644
--- 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"


        


More information about the llvm-commits mailing list