xref: /llvm-project/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp (revision 0b73b5af60f2c544892b9dd68b4fa43eeff52fc1)
1eb02ee44SAnatoly Trosinenko //===-- AArch64PointerAuth.cpp -- Harden code using PAuth ------------------==//
2eb02ee44SAnatoly Trosinenko //
3eb02ee44SAnatoly Trosinenko // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4eb02ee44SAnatoly Trosinenko // See https://llvm.org/LICENSE.txt for license information.
5eb02ee44SAnatoly Trosinenko // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6eb02ee44SAnatoly Trosinenko //
7eb02ee44SAnatoly Trosinenko //===----------------------------------------------------------------------===//
8eb02ee44SAnatoly Trosinenko 
91d2b5582SAnatoly Trosinenko #include "AArch64PointerAuth.h"
101d2b5582SAnatoly Trosinenko 
11eb02ee44SAnatoly Trosinenko #include "AArch64.h"
121d2b5582SAnatoly Trosinenko #include "AArch64InstrInfo.h"
13eb02ee44SAnatoly Trosinenko #include "AArch64MachineFunctionInfo.h"
14eb02ee44SAnatoly Trosinenko #include "AArch64Subtarget.h"
15eb02ee44SAnatoly Trosinenko #include "llvm/CodeGen/MachineBasicBlock.h"
16eb02ee44SAnatoly Trosinenko #include "llvm/CodeGen/MachineInstrBuilder.h"
17eb02ee44SAnatoly Trosinenko #include "llvm/CodeGen/MachineModuleInfo.h"
18eb02ee44SAnatoly Trosinenko 
19eb02ee44SAnatoly Trosinenko using namespace llvm;
201d2b5582SAnatoly Trosinenko using namespace llvm::AArch64PAuth;
21eb02ee44SAnatoly Trosinenko 
22eb02ee44SAnatoly Trosinenko #define AARCH64_POINTER_AUTH_NAME "AArch64 Pointer Authentication"
23eb02ee44SAnatoly Trosinenko 
24eb02ee44SAnatoly Trosinenko namespace {
25eb02ee44SAnatoly Trosinenko 
26eb02ee44SAnatoly Trosinenko class AArch64PointerAuth : public MachineFunctionPass {
27eb02ee44SAnatoly Trosinenko public:
28eb02ee44SAnatoly Trosinenko   static char ID;
29eb02ee44SAnatoly Trosinenko 
30eb02ee44SAnatoly Trosinenko   AArch64PointerAuth() : MachineFunctionPass(ID) {}
31eb02ee44SAnatoly Trosinenko 
32eb02ee44SAnatoly Trosinenko   bool runOnMachineFunction(MachineFunction &MF) override;
33eb02ee44SAnatoly Trosinenko 
34eb02ee44SAnatoly Trosinenko   StringRef getPassName() const override { return AARCH64_POINTER_AUTH_NAME; }
35eb02ee44SAnatoly Trosinenko 
36eb02ee44SAnatoly Trosinenko private:
37eb02ee44SAnatoly Trosinenko   const AArch64Subtarget *Subtarget = nullptr;
38eb02ee44SAnatoly Trosinenko   const AArch64InstrInfo *TII = nullptr;
39eb02ee44SAnatoly Trosinenko 
40eb02ee44SAnatoly Trosinenko   void signLR(MachineFunction &MF, MachineBasicBlock::iterator MBBI) const;
41eb02ee44SAnatoly Trosinenko 
42eb02ee44SAnatoly Trosinenko   void authenticateLR(MachineFunction &MF,
43eb02ee44SAnatoly Trosinenko                       MachineBasicBlock::iterator MBBI) const;
441d2b5582SAnatoly Trosinenko 
4508fccf80SAnatoly Trosinenko   /// Stores blend(AddrDisc, IntDisc) to the Result register.
4608fccf80SAnatoly Trosinenko   void emitBlend(MachineBasicBlock::iterator MBBI, Register Result,
4708fccf80SAnatoly Trosinenko                  Register AddrDisc, unsigned IntDisc) const;
4808fccf80SAnatoly Trosinenko 
4908fccf80SAnatoly Trosinenko   /// Expands PAUTH_BLEND pseudo instruction.
5008fccf80SAnatoly Trosinenko   void expandPAuthBlend(MachineBasicBlock::iterator MBBI) const;
5108fccf80SAnatoly Trosinenko 
521d2b5582SAnatoly Trosinenko   bool checkAuthenticatedLR(MachineBasicBlock::iterator TI) const;
53eb02ee44SAnatoly Trosinenko };
54eb02ee44SAnatoly Trosinenko 
55eb02ee44SAnatoly Trosinenko } // end anonymous namespace
56eb02ee44SAnatoly Trosinenko 
57eb02ee44SAnatoly Trosinenko INITIALIZE_PASS(AArch64PointerAuth, "aarch64-ptrauth",
58eb02ee44SAnatoly Trosinenko                 AARCH64_POINTER_AUTH_NAME, false, false)
59eb02ee44SAnatoly Trosinenko 
60eb02ee44SAnatoly Trosinenko FunctionPass *llvm::createAArch64PointerAuthPass() {
61eb02ee44SAnatoly Trosinenko   return new AArch64PointerAuth();
62eb02ee44SAnatoly Trosinenko }
63eb02ee44SAnatoly Trosinenko 
64eb02ee44SAnatoly Trosinenko char AArch64PointerAuth::ID = 0;
65eb02ee44SAnatoly Trosinenko 
6686f76c3bSJack Styles static void emitPACSymOffsetIntoX16(const TargetInstrInfo &TII,
6786f76c3bSJack Styles                                     MachineBasicBlock &MBB,
6886f76c3bSJack Styles                                     MachineBasicBlock::iterator I, DebugLoc DL,
6986f76c3bSJack Styles                                     MCSymbol *PACSym) {
7086f76c3bSJack Styles   BuildMI(MBB, I, DL, TII.get(AArch64::ADRP), AArch64::X16)
7186f76c3bSJack Styles       .addSym(PACSym, AArch64II::MO_PAGE);
7286f76c3bSJack Styles   BuildMI(MBB, I, DL, TII.get(AArch64::ADDXri), AArch64::X16)
7386f76c3bSJack Styles       .addReg(AArch64::X16)
7486f76c3bSJack Styles       .addSym(PACSym, AArch64II::MO_PAGEOFF | AArch64II::MO_NC)
7586f76c3bSJack Styles       .addImm(0);
7686f76c3bSJack Styles }
7786f76c3bSJack Styles 
787bd17212STomas Matheson // Where PAuthLR support is not known at compile time, it is supported using
797bd17212STomas Matheson // PACM. PACM is in the hint space so has no effect when PAuthLR is not
807bd17212STomas Matheson // supported by the hardware, but will alter the behaviour of PACI*SP, AUTI*SP
817bd17212STomas Matheson // and RETAA/RETAB if the hardware supports PAuthLR.
827bd17212STomas Matheson static void BuildPACM(const AArch64Subtarget &Subtarget, MachineBasicBlock &MBB,
837bd17212STomas Matheson                       MachineBasicBlock::iterator MBBI, DebugLoc DL,
847bd17212STomas Matheson                       MachineInstr::MIFlag Flags, MCSymbol *PACSym = nullptr) {
857bd17212STomas Matheson   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
867bd17212STomas Matheson   auto &MFnI = *MBB.getParent()->getInfo<AArch64FunctionInfo>();
877bd17212STomas Matheson 
8886f76c3bSJack Styles   // Offset to PAC*SP using ADRP + ADD.
897bd17212STomas Matheson   if (PACSym) {
907bd17212STomas Matheson     assert(Flags == MachineInstr::FrameDestroy);
9186f76c3bSJack Styles     emitPACSymOffsetIntoX16(*TII, MBB, MBBI, DL, PACSym);
927bd17212STomas Matheson   }
937bd17212STomas Matheson 
947bd17212STomas Matheson   // Only emit PACM if -mbranch-protection has +pc and the target does not
957bd17212STomas Matheson   // have feature +pauth-lr.
967bd17212STomas Matheson   if (MFnI.branchProtectionPAuthLR() && !Subtarget.hasPAuthLR())
977bd17212STomas Matheson     BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACM)).setMIFlag(Flags);
987bd17212STomas Matheson }
997bd17212STomas Matheson 
10086f76c3bSJack Styles static void emitPACCFI(const AArch64Subtarget &Subtarget,
10186f76c3bSJack Styles                        MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
10286f76c3bSJack Styles                        DebugLoc DL, MachineInstr::MIFlag Flags, bool EmitCFI) {
10386f76c3bSJack Styles   if (!EmitCFI)
10486f76c3bSJack Styles     return;
10586f76c3bSJack Styles 
10686f76c3bSJack Styles   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
10786f76c3bSJack Styles   auto &MF = *MBB.getParent();
10886f76c3bSJack Styles   auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
10986f76c3bSJack Styles 
11086f76c3bSJack Styles   auto CFIInst = MFnI.branchProtectionPAuthLR()
11186f76c3bSJack Styles                      ? MCCFIInstruction::createNegateRAStateWithPC(nullptr)
11286f76c3bSJack Styles                      : MCCFIInstruction::createNegateRAState(nullptr);
11386f76c3bSJack Styles 
11486f76c3bSJack Styles   unsigned CFIIndex = MF.addFrameInst(CFIInst);
11586f76c3bSJack Styles   BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
11686f76c3bSJack Styles       .addCFIIndex(CFIIndex)
11786f76c3bSJack Styles       .setMIFlags(Flags);
11886f76c3bSJack Styles }
11986f76c3bSJack Styles 
120eb02ee44SAnatoly Trosinenko void AArch64PointerAuth::signLR(MachineFunction &MF,
121eb02ee44SAnatoly Trosinenko                                 MachineBasicBlock::iterator MBBI) const {
1227bd17212STomas Matheson   auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
1237bd17212STomas Matheson   bool UseBKey = MFnI.shouldSignWithBKey();
1247bd17212STomas Matheson   bool EmitCFI = MFnI.needsDwarfUnwindInfo(MF);
125eb02ee44SAnatoly Trosinenko   bool NeedsWinCFI = MF.hasWinCFI();
126eb02ee44SAnatoly Trosinenko 
127eb02ee44SAnatoly Trosinenko   MachineBasicBlock &MBB = *MBBI->getParent();
128eb02ee44SAnatoly Trosinenko 
129eb02ee44SAnatoly Trosinenko   // Debug location must be unknown, see AArch64FrameLowering::emitPrologue.
130eb02ee44SAnatoly Trosinenko   DebugLoc DL;
131eb02ee44SAnatoly Trosinenko 
132eb02ee44SAnatoly Trosinenko   if (UseBKey) {
133eb02ee44SAnatoly Trosinenko     BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITBKEY))
134eb02ee44SAnatoly Trosinenko         .setMIFlag(MachineInstr::FrameSetup);
135eb02ee44SAnatoly Trosinenko   }
136eb02ee44SAnatoly Trosinenko 
1377bd17212STomas Matheson   // PAuthLR authentication instructions need to know the value of PC at the
1387bd17212STomas Matheson   // point of signing (PACI*).
1397bd17212STomas Matheson   if (MFnI.branchProtectionPAuthLR()) {
1400f0cfcffSMatt Arsenault     MCSymbol *PACSym = MF.getContext().createTempSymbol();
1417bd17212STomas Matheson     MFnI.setSigningInstrLabel(PACSym);
1427bd17212STomas Matheson   }
1437bd17212STomas Matheson 
144eb02ee44SAnatoly Trosinenko   // No SEH opcode for this one; it doesn't materialize into an
145eb02ee44SAnatoly Trosinenko   // instruction on Windows.
1467bd17212STomas Matheson   if (MFnI.branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
147*0b73b5afSJack Styles     emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameSetup, EmitCFI);
148eb02ee44SAnatoly Trosinenko     BuildMI(MBB, MBBI, DL,
1497bd17212STomas Matheson             TII->get(MFnI.shouldSignWithBKey() ? AArch64::PACIBSPPC
1507bd17212STomas Matheson                                                : AArch64::PACIASPPC))
1517bd17212STomas Matheson         .setMIFlag(MachineInstr::FrameSetup)
1527bd17212STomas Matheson         ->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel());
1537bd17212STomas Matheson   } else {
1547bd17212STomas Matheson     BuildPACM(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameSetup);
155*0b73b5afSJack Styles     emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameSetup, EmitCFI);
1567bd17212STomas Matheson     BuildMI(MBB, MBBI, DL,
1577bd17212STomas Matheson             TII->get(MFnI.shouldSignWithBKey() ? AArch64::PACIBSP
1587bd17212STomas Matheson                                                : AArch64::PACIASP))
1597bd17212STomas Matheson         .setMIFlag(MachineInstr::FrameSetup)
1607bd17212STomas Matheson         ->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel());
1617bd17212STomas Matheson   }
162eb02ee44SAnatoly Trosinenko 
16386f76c3bSJack Styles   if (!EmitCFI && NeedsWinCFI) {
164eb02ee44SAnatoly Trosinenko     BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
165eb02ee44SAnatoly Trosinenko         .setMIFlag(MachineInstr::FrameSetup);
166eb02ee44SAnatoly Trosinenko   }
167eb02ee44SAnatoly Trosinenko }
168eb02ee44SAnatoly Trosinenko 
169eb02ee44SAnatoly Trosinenko void AArch64PointerAuth::authenticateLR(
170eb02ee44SAnatoly Trosinenko     MachineFunction &MF, MachineBasicBlock::iterator MBBI) const {
171eb02ee44SAnatoly Trosinenko   const AArch64FunctionInfo *MFnI = MF.getInfo<AArch64FunctionInfo>();
172eb02ee44SAnatoly Trosinenko   bool UseBKey = MFnI->shouldSignWithBKey();
173eb02ee44SAnatoly Trosinenko   bool EmitAsyncCFI = MFnI->needsAsyncDwarfUnwindInfo(MF);
174eb02ee44SAnatoly Trosinenko   bool NeedsWinCFI = MF.hasWinCFI();
175eb02ee44SAnatoly Trosinenko 
176eb02ee44SAnatoly Trosinenko   MachineBasicBlock &MBB = *MBBI->getParent();
177eb02ee44SAnatoly Trosinenko   DebugLoc DL = MBBI->getDebugLoc();
178eb02ee44SAnatoly Trosinenko   // MBBI points to a PAUTH_EPILOGUE instruction to be replaced and
179eb02ee44SAnatoly Trosinenko   // TI points to a terminator instruction that may or may not be combined.
180eb02ee44SAnatoly Trosinenko   // Note that inserting new instructions "before MBBI" and "before TI" is
181eb02ee44SAnatoly Trosinenko   // not the same because if ShadowCallStack is enabled, its instructions
182eb02ee44SAnatoly Trosinenko   // are placed between MBBI and TI.
183eb02ee44SAnatoly Trosinenko   MachineBasicBlock::iterator TI = MBB.getFirstInstrTerminator();
184eb02ee44SAnatoly Trosinenko 
185eb02ee44SAnatoly Trosinenko   // The AUTIASP instruction assembles to a hint instruction before v8.3a so
186eb02ee44SAnatoly Trosinenko   // this instruction can safely used for any v8a architecture.
187eb02ee44SAnatoly Trosinenko   // From v8.3a onwards there are optimised authenticate LR and return
188eb02ee44SAnatoly Trosinenko   // instructions, namely RETA{A,B}, that can be used instead. In this case the
189eb02ee44SAnatoly Trosinenko   // DW_CFA_AARCH64_negate_ra_state can't be emitted.
190eb02ee44SAnatoly Trosinenko   bool TerminatorIsCombinable =
191eb02ee44SAnatoly Trosinenko       TI != MBB.end() && TI->getOpcode() == AArch64::RET;
1927bd17212STomas Matheson   MCSymbol *PACSym = MFnI->getSigningInstrLabel();
1937bd17212STomas Matheson 
194eb02ee44SAnatoly Trosinenko   if (Subtarget->hasPAuth() && TerminatorIsCombinable && !NeedsWinCFI &&
195eb02ee44SAnatoly Trosinenko       !MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack)) {
1967bd17212STomas Matheson     if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
1977bd17212STomas Matheson       assert(PACSym && "No PAC instruction to refer to");
19886f76c3bSJack Styles       emitPACSymOffsetIntoX16(*TII, MBB, MBBI, DL, PACSym);
1997bd17212STomas Matheson       BuildMI(MBB, TI, DL,
2007bd17212STomas Matheson               TII->get(UseBKey ? AArch64::RETABSPPCi : AArch64::RETAASPPCi))
2017bd17212STomas Matheson           .addSym(PACSym)
2027bd17212STomas Matheson           .copyImplicitOps(*MBBI)
2037bd17212STomas Matheson           .setMIFlag(MachineInstr::FrameDestroy);
2047bd17212STomas Matheson     } else {
2057bd17212STomas Matheson       BuildPACM(*Subtarget, MBB, TI, DL, MachineInstr::FrameDestroy, PACSym);
2067bd17212STomas Matheson       BuildMI(MBB, TI, DL, TII->get(UseBKey ? AArch64::RETAB : AArch64::RETAA))
2077bd17212STomas Matheson           .copyImplicitOps(*MBBI)
2087bd17212STomas Matheson           .setMIFlag(MachineInstr::FrameDestroy);
2097bd17212STomas Matheson     }
210eb02ee44SAnatoly Trosinenko     MBB.erase(TI);
211eb02ee44SAnatoly Trosinenko   } else {
2127bd17212STomas Matheson     if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
2137bd17212STomas Matheson       assert(PACSym && "No PAC instruction to refer to");
21486f76c3bSJack Styles       emitPACSymOffsetIntoX16(*TII, MBB, MBBI, DL, PACSym);
215*0b73b5afSJack Styles       emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy,
216*0b73b5afSJack Styles                  EmitAsyncCFI);
2177bd17212STomas Matheson       BuildMI(MBB, MBBI, DL,
2187bd17212STomas Matheson               TII->get(UseBKey ? AArch64::AUTIBSPPCi : AArch64::AUTIASPPCi))
2197bd17212STomas Matheson           .addSym(PACSym)
220eb02ee44SAnatoly Trosinenko           .setMIFlag(MachineInstr::FrameDestroy);
2217bd17212STomas Matheson     } else {
2227bd17212STomas Matheson       BuildPACM(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy, PACSym);
223*0b73b5afSJack Styles       emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy,
224*0b73b5afSJack Styles                  EmitAsyncCFI);
2257bd17212STomas Matheson       BuildMI(MBB, MBBI, DL,
2267bd17212STomas Matheson               TII->get(UseBKey ? AArch64::AUTIBSP : AArch64::AUTIASP))
2277bd17212STomas Matheson           .setMIFlag(MachineInstr::FrameDestroy);
2287bd17212STomas Matheson     }
229eb02ee44SAnatoly Trosinenko 
230eb02ee44SAnatoly Trosinenko     if (NeedsWinCFI) {
231eb02ee44SAnatoly Trosinenko       BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
232eb02ee44SAnatoly Trosinenko           .setMIFlag(MachineInstr::FrameDestroy);
233eb02ee44SAnatoly Trosinenko     }
234eb02ee44SAnatoly Trosinenko   }
235eb02ee44SAnatoly Trosinenko }
236eb02ee44SAnatoly Trosinenko 
2371d2b5582SAnatoly Trosinenko unsigned llvm::AArch64PAuth::getCheckerSizeInBytes(AuthCheckMethod Method) {
2381d2b5582SAnatoly Trosinenko   switch (Method) {
2391d2b5582SAnatoly Trosinenko   case AuthCheckMethod::None:
2401d2b5582SAnatoly Trosinenko     return 0;
2411d2b5582SAnatoly Trosinenko   case AuthCheckMethod::DummyLoad:
2421d2b5582SAnatoly Trosinenko     return 4;
2431d2b5582SAnatoly Trosinenko   case AuthCheckMethod::HighBitsNoTBI:
2441d2b5582SAnatoly Trosinenko     return 12;
2451d2b5582SAnatoly Trosinenko   case AuthCheckMethod::XPACHint:
24644076c98SAnatoly Trosinenko   case AuthCheckMethod::XPAC:
2471d2b5582SAnatoly Trosinenko     return 20;
2481d2b5582SAnatoly Trosinenko   }
249c0a7dd49SSimon Pilgrim   llvm_unreachable("Unknown AuthCheckMethod enum");
2501d2b5582SAnatoly Trosinenko }
2511d2b5582SAnatoly Trosinenko 
25208fccf80SAnatoly Trosinenko void AArch64PointerAuth::emitBlend(MachineBasicBlock::iterator MBBI,
25308fccf80SAnatoly Trosinenko                                    Register Result, Register AddrDisc,
25408fccf80SAnatoly Trosinenko                                    unsigned IntDisc) const {
25508fccf80SAnatoly Trosinenko   MachineBasicBlock &MBB = *MBBI->getParent();
25608fccf80SAnatoly Trosinenko   DebugLoc DL = MBBI->getDebugLoc();
25708fccf80SAnatoly Trosinenko 
25808fccf80SAnatoly Trosinenko   if (Result != AddrDisc)
25908fccf80SAnatoly Trosinenko     BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), Result)
26008fccf80SAnatoly Trosinenko         .addReg(AArch64::XZR)
26108fccf80SAnatoly Trosinenko         .addReg(AddrDisc)
26208fccf80SAnatoly Trosinenko         .addImm(0);
26308fccf80SAnatoly Trosinenko 
26408fccf80SAnatoly Trosinenko   BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVKXi), Result)
26508fccf80SAnatoly Trosinenko       .addReg(Result)
26608fccf80SAnatoly Trosinenko       .addImm(IntDisc)
26708fccf80SAnatoly Trosinenko       .addImm(48);
26808fccf80SAnatoly Trosinenko }
26908fccf80SAnatoly Trosinenko 
27008fccf80SAnatoly Trosinenko void AArch64PointerAuth::expandPAuthBlend(
27108fccf80SAnatoly Trosinenko     MachineBasicBlock::iterator MBBI) const {
27208fccf80SAnatoly Trosinenko   Register ResultReg = MBBI->getOperand(0).getReg();
27308fccf80SAnatoly Trosinenko   Register AddrDisc = MBBI->getOperand(1).getReg();
27408fccf80SAnatoly Trosinenko   unsigned IntDisc = MBBI->getOperand(2).getImm();
27508fccf80SAnatoly Trosinenko   emitBlend(MBBI, ResultReg, AddrDisc, IntDisc);
27608fccf80SAnatoly Trosinenko }
27708fccf80SAnatoly Trosinenko 
278eb02ee44SAnatoly Trosinenko bool AArch64PointerAuth::runOnMachineFunction(MachineFunction &MF) {
279eb02ee44SAnatoly Trosinenko   Subtarget = &MF.getSubtarget<AArch64Subtarget>();
280eb02ee44SAnatoly Trosinenko   TII = Subtarget->getInstrInfo();
281eb02ee44SAnatoly Trosinenko 
2829bc142a0SAnatoly Trosinenko   SmallVector<MachineBasicBlock::instr_iterator> PAuthPseudoInstrs;
2831d2b5582SAnatoly Trosinenko 
284eb02ee44SAnatoly Trosinenko   bool Modified = false;
285eb02ee44SAnatoly Trosinenko 
286eb02ee44SAnatoly Trosinenko   for (auto &MBB : MF) {
28744076c98SAnatoly Trosinenko     for (auto &MI : MBB) {
288eb02ee44SAnatoly Trosinenko       switch (MI.getOpcode()) {
289eb02ee44SAnatoly Trosinenko       default:
290eb02ee44SAnatoly Trosinenko         break;
291eb02ee44SAnatoly Trosinenko       case AArch64::PAUTH_PROLOGUE:
2929bc142a0SAnatoly Trosinenko       case AArch64::PAUTH_EPILOGUE:
29308fccf80SAnatoly Trosinenko       case AArch64::PAUTH_BLEND:
2949bc142a0SAnatoly Trosinenko         PAuthPseudoInstrs.push_back(MI.getIterator());
2959bc142a0SAnatoly Trosinenko         break;
2969bc142a0SAnatoly Trosinenko       }
2979bc142a0SAnatoly Trosinenko     }
2989bc142a0SAnatoly Trosinenko   }
2999bc142a0SAnatoly Trosinenko 
3009bc142a0SAnatoly Trosinenko   for (auto It : PAuthPseudoInstrs) {
3019bc142a0SAnatoly Trosinenko     switch (It->getOpcode()) {
3029bc142a0SAnatoly Trosinenko     case AArch64::PAUTH_PROLOGUE:
303eb02ee44SAnatoly Trosinenko       signLR(MF, It);
304eb02ee44SAnatoly Trosinenko       break;
305eb02ee44SAnatoly Trosinenko     case AArch64::PAUTH_EPILOGUE:
306eb02ee44SAnatoly Trosinenko       authenticateLR(MF, It);
307eb02ee44SAnatoly Trosinenko       break;
30808fccf80SAnatoly Trosinenko     case AArch64::PAUTH_BLEND:
30908fccf80SAnatoly Trosinenko       expandPAuthBlend(It);
31008fccf80SAnatoly Trosinenko       break;
3119bc142a0SAnatoly Trosinenko     default:
3129bc142a0SAnatoly Trosinenko       llvm_unreachable("Unhandled opcode");
313eb02ee44SAnatoly Trosinenko     }
3149bc142a0SAnatoly Trosinenko     It->eraseFromParent();
3159bc142a0SAnatoly Trosinenko     Modified = true;
316eb02ee44SAnatoly Trosinenko   }
317eb02ee44SAnatoly Trosinenko 
318eb02ee44SAnatoly Trosinenko   return Modified;
319eb02ee44SAnatoly Trosinenko }
320