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