LLVM 19.0.0git
AArch64PointerAuth.cpp
Go to the documentation of this file.
1//===-- AArch64PointerAuth.cpp -- Harden code using PAuth ------------------==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "AArch64.h"
12#include "AArch64InstrInfo.h"
14#include "AArch64Subtarget.h"
19
20using namespace llvm;
21using namespace llvm::AArch64PAuth;
22
23#define AARCH64_POINTER_AUTH_NAME "AArch64 Pointer Authentication"
24
25namespace {
26
27class AArch64PointerAuth : public MachineFunctionPass {
28public:
29 static char ID;
30
31 AArch64PointerAuth() : MachineFunctionPass(ID) {}
32
33 bool runOnMachineFunction(MachineFunction &MF) override;
34
35 StringRef getPassName() const override { return AARCH64_POINTER_AUTH_NAME; }
36
37private:
38 /// An immediate operand passed to BRK instruction, if it is ever emitted.
39 static unsigned BrkOperandForKey(AArch64PACKey::ID KeyId) {
40 const unsigned BrkOperandBase = 0xc470;
41 return BrkOperandBase + KeyId;
42 }
43
44 const AArch64Subtarget *Subtarget = nullptr;
45 const AArch64InstrInfo *TII = nullptr;
46 const AArch64RegisterInfo *TRI = nullptr;
47
48 void signLR(MachineFunction &MF, MachineBasicBlock::iterator MBBI) const;
49
50 void authenticateLR(MachineFunction &MF,
52
53 /// Stores blend(AddrDisc, IntDisc) to the Result register.
54 void emitBlend(MachineBasicBlock::iterator MBBI, Register Result,
55 Register AddrDisc, unsigned IntDisc) const;
56
57 /// Expands PAUTH_BLEND pseudo instruction.
58 void expandPAuthBlend(MachineBasicBlock::iterator MBBI) const;
59
60 bool checkAuthenticatedLR(MachineBasicBlock::iterator TI) const;
61};
62
63} // end anonymous namespace
64
65INITIALIZE_PASS(AArch64PointerAuth, "aarch64-ptrauth",
66 AARCH64_POINTER_AUTH_NAME, false, false)
67
69 return new AArch64PointerAuth();
70}
71
72char AArch64PointerAuth::ID = 0;
73
74// Where PAuthLR support is not known at compile time, it is supported using
75// PACM. PACM is in the hint space so has no effect when PAuthLR is not
76// supported by the hardware, but will alter the behaviour of PACI*SP, AUTI*SP
77// and RETAA/RETAB if the hardware supports PAuthLR.
78static void BuildPACM(const AArch64Subtarget &Subtarget, MachineBasicBlock &MBB,
80 MachineInstr::MIFlag Flags, MCSymbol *PACSym = nullptr) {
81 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
82 auto &MFnI = *MBB.getParent()->getInfo<AArch64FunctionInfo>();
83
84 // ADR X16,<address_of_PACIASP>
85 if (PACSym) {
87 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADR))
88 .addReg(AArch64::X16, RegState::Define)
89 .addSym(PACSym);
90 }
91
92 // Only emit PACM if -mbranch-protection has +pc and the target does not
93 // have feature +pauth-lr.
94 if (MFnI.branchProtectionPAuthLR() && !Subtarget.hasPAuthLR())
95 BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACM)).setMIFlag(Flags);
96}
97
98void AArch64PointerAuth::signLR(MachineFunction &MF,
100 auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
101 bool UseBKey = MFnI.shouldSignWithBKey();
102 bool EmitCFI = MFnI.needsDwarfUnwindInfo(MF);
103 bool NeedsWinCFI = MF.hasWinCFI();
104
106
107 // Debug location must be unknown, see AArch64FrameLowering::emitPrologue.
108 DebugLoc DL;
109
110 if (UseBKey) {
111 BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITBKEY))
113 }
114
115 // PAuthLR authentication instructions need to know the value of PC at the
116 // point of signing (PACI*).
117 if (MFnI.branchProtectionPAuthLR()) {
118 MCSymbol *PACSym = MF.getMMI().getContext().createTempSymbol();
119 MFnI.setSigningInstrLabel(PACSym);
120 }
121
122 // No SEH opcode for this one; it doesn't materialize into an
123 // instruction on Windows.
124 if (MFnI.branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
125 BuildMI(MBB, MBBI, DL,
126 TII->get(MFnI.shouldSignWithBKey() ? AArch64::PACIBSPPC
127 : AArch64::PACIASPPC))
129 ->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel());
130 } else {
132 BuildMI(MBB, MBBI, DL,
133 TII->get(MFnI.shouldSignWithBKey() ? AArch64::PACIBSP
134 : AArch64::PACIASP))
136 ->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel());
137 }
138
139 if (EmitCFI) {
140 unsigned CFIIndex =
142 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
143 .addCFIIndex(CFIIndex)
145 } else if (NeedsWinCFI) {
146 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
148 }
149}
150
151void AArch64PointerAuth::authenticateLR(
154 bool UseBKey = MFnI->shouldSignWithBKey();
155 bool EmitAsyncCFI = MFnI->needsAsyncDwarfUnwindInfo(MF);
156 bool NeedsWinCFI = MF.hasWinCFI();
157
159 DebugLoc DL = MBBI->getDebugLoc();
160 // MBBI points to a PAUTH_EPILOGUE instruction to be replaced and
161 // TI points to a terminator instruction that may or may not be combined.
162 // Note that inserting new instructions "before MBBI" and "before TI" is
163 // not the same because if ShadowCallStack is enabled, its instructions
164 // are placed between MBBI and TI.
166
167 // The AUTIASP instruction assembles to a hint instruction before v8.3a so
168 // this instruction can safely used for any v8a architecture.
169 // From v8.3a onwards there are optimised authenticate LR and return
170 // instructions, namely RETA{A,B}, that can be used instead. In this case the
171 // DW_CFA_AARCH64_negate_ra_state can't be emitted.
172 bool TerminatorIsCombinable =
173 TI != MBB.end() && TI->getOpcode() == AArch64::RET;
174 MCSymbol *PACSym = MFnI->getSigningInstrLabel();
175
176 if (Subtarget->hasPAuth() && TerminatorIsCombinable && !NeedsWinCFI &&
177 !MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack)) {
178 if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
179 assert(PACSym && "No PAC instruction to refer to");
180 BuildMI(MBB, TI, DL,
181 TII->get(UseBKey ? AArch64::RETABSPPCi : AArch64::RETAASPPCi))
182 .addSym(PACSym)
185 } else {
186 BuildPACM(*Subtarget, MBB, TI, DL, MachineInstr::FrameDestroy, PACSym);
187 BuildMI(MBB, TI, DL, TII->get(UseBKey ? AArch64::RETAB : AArch64::RETAA))
190 }
191 MBB.erase(TI);
192 } else {
193 if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
194 assert(PACSym && "No PAC instruction to refer to");
195 BuildMI(MBB, MBBI, DL,
196 TII->get(UseBKey ? AArch64::AUTIBSPPCi : AArch64::AUTIASPPCi))
197 .addSym(PACSym)
199 } else {
200 BuildPACM(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy, PACSym);
201 BuildMI(MBB, MBBI, DL,
202 TII->get(UseBKey ? AArch64::AUTIBSP : AArch64::AUTIASP))
204 }
205
206 if (EmitAsyncCFI) {
207 unsigned CFIIndex =
209 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
210 .addCFIIndex(CFIIndex)
212 }
213 if (NeedsWinCFI) {
214 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
216 }
217 }
218}
219
220namespace {
221
222// Mark dummy LDR instruction as volatile to prevent removing it as dead code.
223MachineMemOperand *createCheckMemOperand(MachineFunction &MF,
224 const AArch64Subtarget &Subtarget) {
225 MachinePointerInfo PointerInfo(Subtarget.getAddressCheckPSV());
226 auto MOVolatileLoad =
228
229 return MF.getMachineMemOperand(PointerInfo, MOVolatileLoad, 4, Align(4));
230}
231
232} // namespace
233
236 Register AuthenticatedReg, Register TmpReg, bool UseIKey, unsigned BrkImm) {
237
240 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
241 const AArch64InstrInfo *TII = Subtarget.getInstrInfo();
242 DebugLoc DL = MBBI->getDebugLoc();
243
244 // All terminator instructions should be grouped at the end of the machine
245 // basic block, with no non-terminator instructions between them. Depending on
246 // the method requested, we will insert some regular instructions, maybe
247 // followed by a conditional branch instruction, which is a terminator, before
248 // MBBI. Thus, MBBI is expected to be the first terminator of its MBB.
249 assert(MBBI->isTerminator() && MBBI == MBB.getFirstTerminator() &&
250 "MBBI should be the first terminator in MBB");
251
252 // First, handle the methods not requiring creating extra MBBs.
253 switch (Method) {
254 default:
255 break;
256 case AuthCheckMethod::None:
257 return;
258 case AuthCheckMethod::DummyLoad:
259 BuildMI(MBB, MBBI, DL, TII->get(AArch64::LDRWui), getWRegFromXReg(TmpReg))
260 .addReg(AuthenticatedReg)
261 .addImm(0)
262 .addMemOperand(createCheckMemOperand(MF, Subtarget));
263 return;
264 }
265
266 // Control flow has to be changed, so arrange new MBBs.
267
268 // The block that explicitly generates a break-point exception on failure.
269 MachineBasicBlock *BreakBlock =
271 MF.push_back(BreakBlock);
272 MBB.addSuccessor(BreakBlock);
273
274 BuildMI(BreakBlock, DL, TII->get(AArch64::BRK)).addImm(BrkImm);
275
276 switch (Method) {
277 case AuthCheckMethod::None:
278 case AuthCheckMethod::DummyLoad:
279 llvm_unreachable("Should be handled above");
280 case AuthCheckMethod::HighBitsNoTBI:
281 BuildMI(MBB, MBBI, DL, TII->get(AArch64::EORXrs), TmpReg)
282 .addReg(AuthenticatedReg)
283 .addReg(AuthenticatedReg)
284 .addImm(1);
285 BuildMI(MBB, MBBI, DL, TII->get(AArch64::TBNZX))
286 .addReg(TmpReg)
287 .addImm(62)
288 .addMBB(BreakBlock);
289 return;
290 case AuthCheckMethod::XPACHint:
291 assert(AuthenticatedReg == AArch64::LR &&
292 "XPACHint mode is only compatible with checking the LR register");
293 assert(UseIKey && "XPACHint mode is only compatible with I-keys");
294 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), TmpReg)
295 .addReg(AArch64::XZR)
296 .addReg(AArch64::LR)
297 .addImm(0);
298 BuildMI(MBB, MBBI, DL, TII->get(AArch64::XPACLRI));
299 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SUBSXrs), AArch64::XZR)
300 .addReg(TmpReg)
301 .addReg(AArch64::LR)
302 .addImm(0);
303 BuildMI(MBB, MBBI, DL, TII->get(AArch64::Bcc))
305 .addMBB(BreakBlock);
306 return;
307 }
308 llvm_unreachable("Unknown AuthCheckMethod enum");
309}
310
312 switch (Method) {
313 case AuthCheckMethod::None:
314 return 0;
315 case AuthCheckMethod::DummyLoad:
316 return 4;
317 case AuthCheckMethod::HighBitsNoTBI:
318 return 12;
319 case AuthCheckMethod::XPACHint:
320 return 20;
321 }
322 llvm_unreachable("Unknown AuthCheckMethod enum");
323}
324
325bool AArch64PointerAuth::checkAuthenticatedLR(
327 const AArch64FunctionInfo *MFnI = TI->getMF()->getInfo<AArch64FunctionInfo>();
328 AArch64PACKey::ID KeyId =
330
332
333 if (Method == AuthCheckMethod::None)
334 return false;
335
336 // FIXME If FEAT_FPAC is implemented by the CPU, this check can be skipped.
337
338 assert(!TI->getMF()->hasWinCFI() && "WinCFI is not yet supported");
339
340 // The following code may create a signing oracle:
341 //
342 // <authenticate LR>
343 // TCRETURN ; the callee may sign and spill the LR in its prologue
344 //
345 // To avoid generating a signing oracle, check the authenticated value
346 // before possibly re-signing it in the callee, as follows:
347 //
348 // <authenticate LR>
349 // <check if LR contains a valid address>
350 // b.<cond> break_block
351 // ret_block:
352 // TCRETURN
353 // break_block:
354 // brk <BrkOperand>
355 //
356 // or just
357 //
358 // <authenticate LR>
359 // ldr tmp, [lr]
360 // TCRETURN
361
362 // TmpReg is chosen assuming X16 and X17 are dead after TI.
364 "Tail call is expected");
365 Register TmpReg =
366 TI->readsRegister(AArch64::X16, TRI) ? AArch64::X17 : AArch64::X16;
367 assert(!TI->readsRegister(TmpReg, TRI) &&
368 "More than a single register is used by TCRETURN");
369
370 checkAuthenticatedRegister(TI, Method, AArch64::LR, TmpReg, /*UseIKey=*/true,
371 BrkOperandForKey(KeyId));
372
373 return true;
374}
375
376void AArch64PointerAuth::emitBlend(MachineBasicBlock::iterator MBBI,
377 Register Result, Register AddrDisc,
378 unsigned IntDisc) const {
380 DebugLoc DL = MBBI->getDebugLoc();
381
382 if (Result != AddrDisc)
383 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), Result)
384 .addReg(AArch64::XZR)
385 .addReg(AddrDisc)
386 .addImm(0);
387
388 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVKXi), Result)
389 .addReg(Result)
390 .addImm(IntDisc)
391 .addImm(48);
392}
393
394void AArch64PointerAuth::expandPAuthBlend(
396 Register ResultReg = MBBI->getOperand(0).getReg();
397 Register AddrDisc = MBBI->getOperand(1).getReg();
398 unsigned IntDisc = MBBI->getOperand(2).getImm();
399 emitBlend(MBBI, ResultReg, AddrDisc, IntDisc);
400}
401
402bool AArch64PointerAuth::runOnMachineFunction(MachineFunction &MF) {
403 const auto *MFnI = MF.getInfo<AArch64FunctionInfo>();
404
405 Subtarget = &MF.getSubtarget<AArch64Subtarget>();
406 TII = Subtarget->getInstrInfo();
407 TRI = Subtarget->getRegisterInfo();
408
411
412 bool Modified = false;
413 bool HasAuthenticationInstrs = false;
414
415 for (auto &MBB : MF) {
416 // Using instr_iterator to catch unsupported bundled TCRETURN* instructions
417 // instead of just skipping them.
418 for (auto &MI : MBB.instrs()) {
419 switch (MI.getOpcode()) {
420 default:
421 // Bundled TCRETURN* instructions (such as created by KCFI)
422 // are not supported yet, but no support is required if no
423 // PAUTH_EPILOGUE instructions exist in the same function.
424 // Skip the BUNDLE instruction itself (actual bundled instructions
425 // follow it in the instruction list).
426 if (MI.isBundle())
427 continue;
429 TailCallInstrs.push_back(MI.getIterator());
430 break;
431 case AArch64::PAUTH_PROLOGUE:
432 case AArch64::PAUTH_EPILOGUE:
433 case AArch64::PAUTH_BLEND:
434 assert(!MI.isBundled());
435 PAuthPseudoInstrs.push_back(MI.getIterator());
436 break;
437 }
438 }
439 }
440
441 for (auto It : PAuthPseudoInstrs) {
442 switch (It->getOpcode()) {
443 case AArch64::PAUTH_PROLOGUE:
444 signLR(MF, It);
445 break;
446 case AArch64::PAUTH_EPILOGUE:
447 authenticateLR(MF, It);
448 HasAuthenticationInstrs = true;
449 break;
450 case AArch64::PAUTH_BLEND:
451 expandPAuthBlend(It);
452 break;
453 default:
454 llvm_unreachable("Unhandled opcode");
455 }
456 It->eraseFromParent();
457 Modified = true;
458 }
459
460 // FIXME Do we need to emit any PAuth-related epilogue code at all
461 // when SCS is enabled?
462 if (HasAuthenticationInstrs &&
464 for (auto TailCall : TailCallInstrs) {
465 assert(!TailCall->isBundled() && "Not yet supported");
466 Modified |= checkAuthenticatedLR(TailCall);
467 }
468 }
469
470 return Modified;
471}
#define AARCH64_POINTER_AUTH_NAME
static void BuildPACM(const AArch64Subtarget &Subtarget, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL, MachineInstr::MIFlag Flags, MCSymbol *PACSym=nullptr)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
bool needsShadowCallStackPrologueEpilogue(MachineFunction &MF) const
bool needsAsyncDwarfUnwindInfo(const MachineFunction &MF) const
static bool isTailCallReturnInst(const MachineInstr &MI)
Returns true if MI is one of the TCRETURN* instructions.
const AArch64InstrInfo * getInstrInfo() const override
const PseudoSourceValue * getAddressCheckPSV() const
AArch64PAuth::AuthCheckMethod getAuthenticatedLRCheckMethod() const
Choose a method of checking LR before performing a tail call.
A debug info location.
Definition: DebugLoc.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:680
static MCCFIInstruction createNegateRAState(MCSymbol *L, SMLoc Loc={})
.cfi_negate_ra_state AArch64 negate RA state.
Definition: MCDwarf.h:609
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:322
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
void push_back(MachineBasicBlock *MBB)
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineModuleInfo & getMMI() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
void setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol)
Set a symbol that will be emitted just prior to the instruction itself.
A description of a memory reference used in the backend.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
const MCContext & getContext() const
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
TargetInstrInfo - Interface to description of machine instruction set.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getCheckerSizeInBytes(AuthCheckMethod Method)
Returns the number of bytes added by checkAuthenticatedRegister.
void checkAuthenticatedRegister(MachineBasicBlock::iterator MBBI, AuthCheckMethod Method, Register AuthenticatedReg, Register TmpReg, bool UseIKey, unsigned BrkImm)
Explicitly checks that pointer authentication succeeded.
AuthCheckMethod
Variants of check performed on an authenticated pointer.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ Define
Register definition.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createAArch64PointerAuthPass()
static unsigned getWRegFromXReg(unsigned Reg)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
This class contains a discriminated union of information about pointers in memory operands,...