LLVM 24.0.0git
AArch64PrologueEpilogue.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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
12#include "AArch64PointerAuth.h"
13#include "AArch64Subtarget.h"
15#include "llvm/ADT/Statistic.h"
18#include "llvm/MC/MCContext.h"
19
20#define DEBUG_TYPE "frame-info"
21
22STATISTIC(NumRedZoneFunctions, "Number of functions using red zone");
23
24namespace llvm {
25
26static bool matchLibcall(const TargetLowering &TLI, const MachineOperand &MO,
27 RTLIB::Libcall LC) {
28 return MO.isSymbol() &&
29 StringRef(TLI.getLibcallName(LC)) == MO.getSymbolName();
30}
31
33 return AFI->hasStreamingModeChanges() &&
34 !MF.getSubtarget<AArch64Subtarget>().hasSVE();
35}
36
39 unsigned Opc = MBBI->getOpcode();
40 if (Opc == AArch64::CNTD_XPiI)
41 return true;
42
43 if (!requiresGetVGCall())
44 return false;
45
46 if (Opc == AArch64::BL)
47 return matchLibcall(TLI, MBBI->getOperand(0), RTLIB::SMEABI_GET_CURRENT_VG);
48
49 return Opc == TargetOpcode::COPY;
50}
51
52// Convenience function to determine whether I is part of the ZPR callee saves.
54 switch (I->getOpcode()) {
55 default:
56 return false;
57 case AArch64::LD1B_2Z_IMM:
58 case AArch64::ST1B_2Z_IMM:
59 case AArch64::LD1B_4Z_IMM:
60 case AArch64::ST1B_4Z_IMM:
61 case AArch64::STR_ZXI:
62 case AArch64::LDR_ZXI:
63 case AArch64::PTRUE_C_B:
64 return I->getFlag(MachineInstr::FrameSetup) ||
66 case AArch64::SEH_SaveZReg:
67 return true;
68 }
69}
70
71// Convenience function to determine whether I is part of the PPR callee saves.
73 switch (I->getOpcode()) {
74 default:
75 return false;
76 case AArch64::STR_PXI:
77 case AArch64::LDR_PXI:
78 return I->getFlag(MachineInstr::FrameSetup) ||
80 case AArch64::SEH_SavePReg:
81 return true;
82 }
83}
84
85// Convenience function to determine whether I is part of the SVE callee saves.
89
93 : MF(MF), MBB(MBB), MFI(MF.getFrameInfo()),
94 Subtarget(MF.getSubtarget<AArch64Subtarget>()), AFL(AFL),
95 RegInfo(*Subtarget.getRegisterInfo()) {
96 TII = Subtarget.getInstrInfo();
97 AFI = MF.getInfo<AArch64FunctionInfo>();
98
99 HasFP = AFL.hasFP(MF);
100 NeedsWinCFI = MF.needsWinCFI();
101
102 if (AFL.hasSVECalleeSavesAboveFrameRecord(MF)) {
103 if (AFI->hasStackHazardSlotIndex())
104 reportFatalUsageError("SME hazard padding is not supported on Windows");
105 SVELayout = SVEStackLayout::CalleeSavesAboveFrameRecord;
106 } else if (AFI->hasSplitSVEObjects()) {
107 SVELayout = SVEStackLayout::Split;
108 }
109}
110
113 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, int CSStackSizeInc,
114 bool EmitCFI, MachineInstr::MIFlag FrameFlag, int CFAOffset) const {
115 unsigned NewOpc;
116
117 // If the function contains streaming mode changes, we expect instructions
118 // to calculate the value of VG before spilling. Move past these instructions
119 // if necessary.
120 if (AFL.requiresSaveVG(MF)) {
121 auto &TLI = *Subtarget.getTargetLowering();
122 while (isVGInstruction(MBBI, TLI))
123 ++MBBI;
124 }
125
126 switch (MBBI->getOpcode()) {
127 default:
128 llvm_unreachable("Unexpected callee-save save/restore opcode!");
129 case AArch64::STPXi:
130 NewOpc = AArch64::STPXpre;
131 break;
132 case AArch64::STPDi:
133 NewOpc = AArch64::STPDpre;
134 break;
135 case AArch64::STPQi:
136 NewOpc = AArch64::STPQpre;
137 break;
138 case AArch64::STRXui:
139 NewOpc = AArch64::STRXpre;
140 break;
141 case AArch64::STRDui:
142 NewOpc = AArch64::STRDpre;
143 break;
144 case AArch64::STRQui:
145 NewOpc = AArch64::STRQpre;
146 break;
147 case AArch64::LDPXi:
148 NewOpc = AArch64::LDPXpost;
149 break;
150 case AArch64::LDPDi:
151 NewOpc = AArch64::LDPDpost;
152 break;
153 case AArch64::LDPQi:
154 NewOpc = AArch64::LDPQpost;
155 break;
156 case AArch64::LDRXui:
157 NewOpc = AArch64::LDRXpost;
158 break;
159 case AArch64::LDRDui:
160 NewOpc = AArch64::LDRDpost;
161 break;
162 case AArch64::LDRQui:
163 NewOpc = AArch64::LDRQpost;
164 break;
165 }
166 TypeSize Scale = TypeSize::getFixed(1), Width = TypeSize::getFixed(0);
167 int64_t MinOffset, MaxOffset;
168 bool Success = TII->getMemOpInfo(NewOpc, Scale, Width, MinOffset, MaxOffset);
169 (void)Success;
170 assert(Success && "unknown load/store opcode");
171
172 // If the first store isn't right where we want SP then we can't fold the
173 // update in so create a normal arithmetic instruction instead.
174 //
175 // On Windows, some register pairs involving LR can't be folded because
176 // there isn't a corresponding unwind opcode.
177 if (MBBI->getOperand(MBBI->getNumOperands() - 1).getImm() != 0 ||
178 CSStackSizeInc < MinOffset * (int64_t)Scale.getFixedValue() ||
179 CSStackSizeInc > MaxOffset * (int64_t)Scale.getFixedValue() ||
180 (NeedsWinCFI &&
181 (NewOpc == AArch64::LDPXpost || NewOpc == AArch64::STPXpre) &&
182 RegInfo.getEncodingValue(MBBI->getOperand(0).getReg()) + 1 !=
183 RegInfo.getEncodingValue(MBBI->getOperand(1).getReg()))) {
184 // If we are destroying the frame, make sure we add the increment after the
185 // last frame operation.
186 if (FrameFlag == MachineInstr::FrameDestroy) {
187 ++MBBI;
188 // Also skip the SEH instruction, if needed
189 if (NeedsWinCFI && AArch64InstrInfo::isSEHInstruction(*MBBI))
190 ++MBBI;
191 }
192 emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
193 StackOffset::getFixed(CSStackSizeInc), TII, FrameFlag,
194 false, NeedsWinCFI, &HasWinCFI, EmitCFI,
195 StackOffset::getFixed(CFAOffset));
196
197 return std::prev(MBBI);
198 }
199
200 // Get rid of the SEH code associated with the old instruction.
201 if (NeedsWinCFI) {
202 auto SEH = std::next(MBBI);
203 if (AArch64InstrInfo::isSEHInstruction(*SEH))
204 SEH->eraseFromParent();
205 }
206
207 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc));
208 MIB.addReg(AArch64::SP, RegState::Define);
209
210 // Copy all operands other than the immediate offset.
211 unsigned OpndIdx = 0;
212 for (unsigned OpndEnd = MBBI->getNumOperands() - 1; OpndIdx < OpndEnd;
213 ++OpndIdx)
214 MIB.add(MBBI->getOperand(OpndIdx));
215
216 assert(MBBI->getOperand(OpndIdx).getImm() == 0 &&
217 "Unexpected immediate offset in first/last callee-save save/restore "
218 "instruction!");
219 assert(MBBI->getOperand(OpndIdx - 1).getReg() == AArch64::SP &&
220 "Unexpected base register in callee-save save/restore instruction!");
221 assert(CSStackSizeInc % Scale == 0);
222 MIB.addImm(CSStackSizeInc / (int)Scale);
223
224 MIB.setMIFlags(MBBI->getFlags());
225 MIB.setMemRefs(MBBI->memoperands());
226
227 // Generate a new SEH code that corresponds to the new instruction.
228 if (NeedsWinCFI) {
229 HasWinCFI = true;
230 AFL.insertSEH(*MIB, *TII, FrameFlag);
231 }
232
233 if (EmitCFI)
234 CFIInstBuilder(MBB, MBBI, FrameFlag)
235 .buildDefCFAOffset(CFAOffset - CSStackSizeInc);
236
237 return std::prev(MBB.erase(MBBI));
238}
239
240// Fix up the SEH opcode associated with the save/restore instruction.
242 unsigned LocalStackSize) {
243 MachineOperand *ImmOpnd = nullptr;
244 unsigned ImmIdx = MBBI->getNumOperands() - 1;
245 switch (MBBI->getOpcode()) {
246 default:
247 llvm_unreachable("Fix the offset in the SEH instruction");
248 case AArch64::SEH_SaveFPLR:
249 case AArch64::SEH_SaveRegP:
250 case AArch64::SEH_SaveReg:
251 case AArch64::SEH_SaveFRegP:
252 case AArch64::SEH_SaveFReg:
253 case AArch64::SEH_SaveAnyRegI:
254 case AArch64::SEH_SaveAnyRegIP:
255 case AArch64::SEH_SaveAnyRegQ:
256 case AArch64::SEH_SaveAnyRegQX:
257 case AArch64::SEH_SaveAnyRegQP:
258 case AArch64::SEH_SaveAnyRegQPX:
259 ImmOpnd = &MBBI->getOperand(ImmIdx);
260 break;
261 }
262 if (ImmOpnd)
263 ImmOpnd->setImm(ImmOpnd->getImm() + LocalStackSize);
264}
265
267 MachineInstr &MI, uint64_t LocalStackSize) const {
268 if (AArch64InstrInfo::isSEHInstruction(MI))
269 return;
270
271 unsigned Opc = MI.getOpcode();
272 unsigned Scale;
273 switch (Opc) {
274 case AArch64::STPXi:
275 case AArch64::STRXui:
276 case AArch64::STPDi:
277 case AArch64::STRDui:
278 case AArch64::LDPXi:
279 case AArch64::LDRXui:
280 case AArch64::LDPDi:
281 case AArch64::LDRDui:
282 Scale = 8;
283 break;
284 case AArch64::STPQi:
285 case AArch64::STRQui:
286 case AArch64::LDPQi:
287 case AArch64::LDRQui:
288 Scale = 16;
289 break;
290 default:
291 llvm_unreachable("Unexpected callee-save save/restore opcode!");
292 }
293
294 unsigned OffsetIdx = MI.getNumExplicitOperands() - 1;
295 assert(MI.getOperand(OffsetIdx - 1).getReg() == AArch64::SP &&
296 "Unexpected base register in callee-save save/restore instruction!");
297 // Last operand is immediate offset that needs fixing.
298 MachineOperand &OffsetOpnd = MI.getOperand(OffsetIdx);
299 // All generated opcodes have scaled offsets.
300 assert(LocalStackSize % Scale == 0);
301 OffsetOpnd.setImm(OffsetOpnd.getImm() + LocalStackSize / Scale);
302
303 if (NeedsWinCFI) {
304 HasWinCFI = true;
305 auto MBBI = std::next(MachineBasicBlock::iterator(MI));
306 assert(MBBI != MI.getParent()->end() && "Expecting a valid instruction");
307 assert(AArch64InstrInfo::isSEHInstruction(*MBBI) &&
308 "Expecting a SEH instruction");
309 fixupSEHOpcode(MBBI, LocalStackSize);
310 }
311}
312
314 uint64_t StackBumpBytes) const {
315 if (AFL.homogeneousPrologEpilog(MF))
316 return false;
317
318 if (AFI->getLocalStackSize() == 0)
319 return false;
320
321 // For WinCFI, if optimizing for size, prefer to not combine the stack bump
322 // (to force a stp with predecrement) to match the packed unwind format,
323 // provided that there actually are any callee saved registers to merge the
324 // decrement with.
325 //
326 // Note that for certain paired saves, like "x19, lr", we can't actually
327 // emit an predecrement stp, but packed unwind still expects a separate stack
328 // adjustment.
329 //
330 // This is potentially marginally slower, but allows using the packed
331 // unwind format for functions that both have a local area and callee saved
332 // registers. Using the packed unwind format notably reduces the size of
333 // the unwind info.
334 if (MF.needsWinCFI() && AFI->getCalleeSavedStackSize() > 0 &&
335 MF.getFunction().hasOptSize())
336 return false;
337
338 // 512 is the maximum immediate for stp/ldp that will be used for
339 // callee-save save/restores
340 if (StackBumpBytes >= 512 ||
341 AFL.windowsRequiresStackProbe(MF, StackBumpBytes))
342 return false;
343
344 if (MFI.hasVarSizedObjects())
345 return false;
346
347 if (RegInfo.hasStackRealignment(MF))
348 return false;
349
350 // This isn't strictly necessary, but it simplifies things a bit since the
351 // current RedZone handling code assumes the SP is adjusted by the
352 // callee-save save/restore code.
353 if (AFL.canUseRedZone(MF))
354 return false;
355
356 // When there is an SVE area on the stack, always allocate the
357 // callee-saves and spills/locals separately.
358 if (AFI->hasSVEStackSize())
359 return false;
360
361 return true;
362}
363
365 StackOffset PPRCalleeSavesSize =
366 StackOffset::getScalable(AFI->getPPRCalleeSavedStackSize());
367 StackOffset ZPRCalleeSavesSize =
368 StackOffset::getScalable(AFI->getZPRCalleeSavedStackSize());
369 StackOffset PPRLocalsSize = AFL.getPPRStackSize(MF) - PPRCalleeSavesSize;
370 StackOffset ZPRLocalsSize = AFL.getZPRStackSize(MF) - ZPRCalleeSavesSize;
372 return {{PPRCalleeSavesSize, PPRLocalsSize},
373 {ZPRCalleeSavesSize, ZPRLocalsSize}};
374 // For simplicity, attribute all locals to ZPRs when split SVE is disabled.
375 return {{PPRCalleeSavesSize, StackOffset{}},
376 {ZPRCalleeSavesSize, PPRLocalsSize + ZPRLocalsSize}};
377}
378
380 SVEFrameSizes const &SVE) {
381 StackOffset AfterZPRs = SVE.ZPR.LocalsSize;
382 StackOffset BeforePPRs = SVE.ZPR.CalleeSavesSize + SVE.PPR.CalleeSavesSize;
383 StackOffset AfterPPRs = {};
385 BeforePPRs = SVE.PPR.CalleeSavesSize;
386 // If there are no ZPR CSRs, place all local allocations after the ZPRs.
387 if (SVE.ZPR.CalleeSavesSize)
388 AfterPPRs += SVE.PPR.LocalsSize + SVE.ZPR.CalleeSavesSize;
389 else
390 AfterZPRs += SVE.PPR.LocalsSize; // Group allocation of locals.
391 }
392 return {BeforePPRs, AfterPPRs, AfterZPRs};
393}
394
400
403 StackOffset PPRCalleeSavesSize,
404 StackOffset ZPRCalleeSavesSize,
405 bool IsEpilogue) {
408 IsEpilogue ? MBB.begin() : MBB.getFirstTerminator();
409 auto AdjustI = [&](auto MBBI) { return IsEpilogue ? std::prev(MBBI) : MBBI; };
410 // Process the SVE CS to find the starts/ends of the ZPR and PPR areas.
411 if (PPRCalleeSavesSize) {
412 PPRsI = AdjustI(PPRsI);
413 assert(isPartOfPPRCalleeSaves(*PPRsI) && "Unexpected instruction");
414 while (PPRsI != End && isPartOfPPRCalleeSaves(AdjustI(PPRsI)))
415 IsEpilogue ? (--PPRsI) : (++PPRsI);
416 }
417 MachineBasicBlock::iterator ZPRsI = PPRsI;
418 if (ZPRCalleeSavesSize) {
419 ZPRsI = AdjustI(ZPRsI);
420 assert(isPartOfZPRCalleeSaves(*ZPRsI) && "Unexpected instruction");
421 while (ZPRsI != End && isPartOfZPRCalleeSaves(AdjustI(ZPRsI)))
422 IsEpilogue ? (--ZPRsI) : (++ZPRsI);
423 }
424 if (IsEpilogue)
425 return {{PPRsI, MBBI}, {ZPRsI, PPRsI}};
426 return {{MBBI, PPRsI}, {PPRsI, ZPRsI}};
427}
428
433 EmitCFI = AFI->needsDwarfUnwindInfo(MF);
434 EmitAsyncCFI = AFI->needsAsyncDwarfUnwindInfo(MF);
435 IsFunclet = MBB.isEHFuncletEntry();
436 HomPrologEpilog = AFL.homogeneousPrologEpilog(MF);
437
438#ifndef NDEBUG
439 collectBlockLiveins();
440#endif
441}
442
443#ifndef NDEBUG
444/// Collect live registers from the end of \p MI's parent up to (including) \p
445/// MI in \p LiveRegs.
448
449 MachineBasicBlock &MBB = *MI.getParent();
450 LiveRegs.addLiveOuts(MBB);
451 for (const MachineInstr &MI :
452 reverse(make_range(MI.getIterator(), MBB.instr_end())))
453 LiveRegs.stepBackward(MI);
454}
455
456void AArch64PrologueEmitter::collectBlockLiveins() {
457 // Collect live register from the end of MBB up to the start of the existing
458 // frame setup instructions.
459 PrologueEndI = MBB.begin();
460 while (PrologueEndI != MBB.end() &&
461 PrologueEndI->getFlag(MachineInstr::FrameSetup))
462 ++PrologueEndI;
463
464 if (PrologueEndI != MBB.end()) {
465 getLivePhysRegsUpTo(*PrologueEndI, RegInfo, LiveRegs);
466 // Ignore registers used for stack management for now.
467 LiveRegs.removeReg(AArch64::SP);
468 LiveRegs.removeReg(AArch64::X19);
469 LiveRegs.removeReg(AArch64::FP);
470 LiveRegs.removeReg(AArch64::LR);
471
472 // X0 will be clobbered by a call to __arm_get_current_vg in the prologue.
473 // This is necessary to spill VG if required where SVE is unavailable, but
474 // X0 is preserved around this call.
475 if (requiresGetVGCall())
476 LiveRegs.removeReg(AArch64::X0);
477 }
478}
479
480void AArch64PrologueEmitter::verifyPrologueClobbers() const {
481 if (PrologueEndI == MBB.end())
482 return;
483 // Check if any of the newly instructions clobber any of the live registers.
484 for (MachineInstr &MI :
485 make_range(MBB.instr_begin(), PrologueEndI->getIterator())) {
486 for (auto &Op : MI.operands())
487 if (Op.isReg() && Op.isDef())
488 assert(!LiveRegs.contains(Op.getReg()) &&
489 "live register clobbered by inserted prologue instructions");
490 }
491}
492#endif
493
494void AArch64PrologueEmitter::determineLocalsStackSize(
495 uint64_t StackSize, uint64_t PrologueSaveSize) {
496 AFI->setLocalStackSize(StackSize - PrologueSaveSize);
497 CombineSPBump = shouldCombineCSRLocalStackBump(StackSize);
498}
499
500// Return the maximum possible number of bytes for `Size` due to the
501// architectural limit on the size of a SVE register.
502static int64_t upperBound(StackOffset Size) {
503 static const int64_t MAX_BYTES_PER_SCALABLE_BYTE = 16;
504 return Size.getScalable() * MAX_BYTES_PER_SCALABLE_BYTE + Size.getFixed();
505}
506
507void AArch64PrologueEmitter::allocateStackSpace(
508 MachineBasicBlock::iterator MBBI, int64_t RealignmentPadding,
509 StackOffset AllocSize, bool EmitCFI, StackOffset InitialOffset,
510 bool FollowupAllocs) {
511
512 if (!AllocSize)
513 return;
514
515 DebugLoc DL;
516 const int64_t MaxAlign = MFI.getMaxAlign().value();
517 const uint64_t AndMask = ~(MaxAlign - 1);
518
519 if (!Subtarget.getTargetLowering()->hasInlineStackProbe(MF)) {
520 Register TargetReg = RealignmentPadding
521 ? AFL.findScratchNonCalleeSaveRegister(&MBB)
522 : AArch64::SP;
523 // SUB Xd/SP, SP, AllocSize
524 emitFrameOffset(MBB, MBBI, DL, TargetReg, AArch64::SP, -AllocSize, TII,
526 EmitCFI, InitialOffset);
527
528 if (RealignmentPadding) {
529 // AND SP, X9, 0b11111...0000
530 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ANDXri), AArch64::SP)
531 .addReg(TargetReg, RegState::Kill)
534 AFI->setStackRealigned(true);
535
536 // No need for SEH instructions here; if we're realigning the stack,
537 // we've set a frame pointer and already finished the SEH prologue.
539 }
540 return;
541 }
542
543 //
544 // Stack probing allocation.
545 //
546
547 // Fixed length allocation. If we don't need to re-align the stack and don't
548 // have SVE objects, we can use a more efficient sequence for stack probing.
549 if (AllocSize.getScalable() == 0 && RealignmentPadding == 0) {
550 Register ScratchReg = AFL.findScratchNonCalleeSaveRegister(&MBB);
551 assert(ScratchReg.isValid());
552 BuildMI(MBB, MBBI, DL, TII->get(AArch64::PROBED_STACKALLOC))
553 .addDef(ScratchReg)
554 .addImm(AllocSize.getFixed())
555 .addImm(InitialOffset.getFixed())
556 .addImm(InitialOffset.getScalable());
557 // The fixed allocation may leave unprobed bytes at the top of the
558 // stack. If we have subsequent allocation (e.g. if we have variable-sized
559 // objects), we need to issue an extra probe, so these allocations start in
560 // a known state.
561 if (FollowupAllocs) {
562 // LDR XZR, [SP]
563 BuildMI(MBB, MBBI, DL, TII->get(AArch64::LDRXui))
564 .addDef(AArch64::XZR)
565 .addReg(AArch64::SP)
566 .addImm(0)
567 .addMemOperand(MF.getMachineMemOperand(
570 Align(8)))
572 }
573
574 return;
575 }
576
577 // Variable length allocation.
578
579 // If the (unknown) allocation size cannot exceed the probe size, decrement
580 // the stack pointer right away.
581 int64_t ProbeSize = AFI->getStackProbeSize();
582 if (upperBound(AllocSize) + RealignmentPadding <= ProbeSize) {
583 Register ScratchReg = RealignmentPadding
584 ? AFL.findScratchNonCalleeSaveRegister(&MBB)
585 : AArch64::SP;
586 assert(ScratchReg.isValid());
587 // SUB Xd, SP, AllocSize
588 emitFrameOffset(MBB, MBBI, DL, ScratchReg, AArch64::SP, -AllocSize, TII,
590 EmitCFI, InitialOffset);
591 if (RealignmentPadding) {
592 // AND SP, Xn, 0b11111...0000
593 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ANDXri), AArch64::SP)
594 .addReg(ScratchReg, RegState::Kill)
597 AFI->setStackRealigned(true);
598 }
599 if (FollowupAllocs || upperBound(AllocSize) + RealignmentPadding >
601 // LDR XZR, [SP]
602 BuildMI(MBB, MBBI, DL, TII->get(AArch64::LDRXui))
603 .addDef(AArch64::XZR)
604 .addReg(AArch64::SP)
605 .addImm(0)
606 .addMemOperand(MF.getMachineMemOperand(
609 Align(8)))
611 }
612 return;
613 }
614
615 // Emit a variable-length allocation probing loop.
616 // TODO: As an optimisation, the loop can be "unrolled" into a few parts,
617 // each of them guaranteed to adjust the stack by less than the probe size.
618 Register TargetReg = AFL.findScratchNonCalleeSaveRegister(&MBB);
619 assert(TargetReg.isValid());
620 // SUB Xd, SP, AllocSize
621 emitFrameOffset(MBB, MBBI, DL, TargetReg, AArch64::SP, -AllocSize, TII,
623 EmitCFI, InitialOffset);
624 if (RealignmentPadding) {
625 // AND Xn, Xn, 0b11111...0000
626 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ANDXri), TargetReg)
627 .addReg(TargetReg, RegState::Kill)
630 }
631
632 BuildMI(MBB, MBBI, DL, TII->get(AArch64::PROBED_STACKALLOC_VAR))
633 .addReg(TargetReg);
634 if (EmitCFI) {
635 // Set the CFA register back to SP.
636 CFIInstBuilder(MBB, MBBI, MachineInstr::FrameSetup)
637 .buildDefCFARegister(AArch64::SP);
638 }
639 if (RealignmentPadding)
640 AFI->setStackRealigned(true);
641}
642
644 const MachineBasicBlock::iterator PrologueBeginI = MBB.begin();
645 const MachineBasicBlock::iterator EndI = MBB.end();
646
647 // At this point, we're going to decide whether or not the function uses a
648 // redzone. In most cases, the function doesn't have a redzone so let's
649 // assume that's false and set it to true in the case that there's a redzone.
650 AFI->setHasRedZone(false);
651
652 // Debug location must be unknown since the first debug location is used
653 // to determine the end of the prologue.
654 DebugLoc DL;
655
656 // In some cases, particularly with CallingConv::SwiftTail, it is possible to
657 // have a tail-call where the caller only needs to adjust the stack pointer in
658 // the epilogue. In this case, we still need to emit a SEH prologue sequence.
659 // See `seh-minimal-prologue-epilogue.ll` test cases.
660 if (int64_t ArgBytes = AFI->getArgumentStackToRestore()) {
662
663 // The callee pops its stack arguments, so once the unwinder has undone
664 // the prologue it must also pop them to recover the caller's SP. The
665 // opcodes before end_c don't correspond to instructions, so describe the
666 // pop there.
667 if (NeedsWinCFI && !IsFunclet) {
668 BuildMI(MBB, PrologueBeginI, DL, TII->get(AArch64::SEH_StackAlloc))
669 .addImm(ArgBytes)
671 BuildMI(MBB, PrologueBeginI, DL, TII->get(AArch64::SEH_EndC))
673 }
674 }
675
676 if (AFI->shouldSignReturnAddress(MF)) {
677 // If pac-ret+leaf is in effect, PAUTH_PROLOGUE pseudo instructions
678 // are inserted by emitPacRetPlusLeafHardening().
679 if (!AFL.shouldSignReturnAddressEverywhere(MF)) {
680 BuildMI(MBB, PrologueBeginI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
682 }
683 // AArch64PointerAuth pass will insert SEH_PACSignLR
685 }
686
687 if (AFI->needsShadowCallStackPrologueEpilogue(MF)) {
688 emitShadowCallStackPrologue(PrologueBeginI, DL);
690 }
691
692 if (EmitCFI && AFI->isMTETagged())
693 BuildMI(MBB, PrologueBeginI, DL, TII->get(AArch64::EMITMTETAGGED))
695
696 // We signal the presence of a Swift extended frame to external tools by
697 // storing FP with 0b0001 in bits 63:60. In normal userland operation a simple
698 // ORR is sufficient, it is assumed a Swift kernel would initialize the TBI
699 // bits so that is still true.
700 if (HasFP && AFI->hasSwiftAsyncContext())
701 emitSwiftAsyncContextFramePointer(PrologueBeginI, DL);
702
703 // All calls are tail calls in GHC calling conv, and functions have no
704 // prologue/epilogue.
705 if (MF.getFunction().getCallingConv() == CallingConv::GHC)
706 return;
707
708 // Set tagged base pointer to the requested stack slot. Ideally it should
709 // match SP value after prologue.
710 if (std::optional<int> TBPI = AFI->getTaggedBasePointerIndex())
711 AFI->setTaggedBasePointerOffset(-MFI.getObjectOffset(*TBPI));
712 else
713 AFI->setTaggedBasePointerOffset(MFI.getStackSize());
714
715 // getStackSize() includes all the locals in its size calculation. We don't
716 // include these locals when computing the stack size of a funclet, as they
717 // are allocated in the parent's stack frame and accessed via the frame
718 // pointer from the funclet. We only save the callee saved registers in the
719 // funclet, which are really the callee saved registers of the parent
720 // function, including the funclet.
721 int64_t NumBytes =
722 IsFunclet ? AFL.getWinEHFuncletFrameSize(MF) : MFI.getStackSize();
723 if (!AFI->hasStackFrame() && !AFL.windowsRequiresStackProbe(MF, NumBytes))
724 return emitEmptyStackFramePrologue(NumBytes, PrologueBeginI, DL);
725
726 bool IsWin64 = Subtarget.isCallingConvWin64(F.getCallingConv(), F.isVarArg());
727 unsigned FixedObject = AFL.getFixedObjectSize(MF, AFI, IsWin64, IsFunclet);
728
729 auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject;
730 // All of the remaining stack allocations are for locals.
731 determineLocalsStackSize(NumBytes, PrologueSaveSize);
732
733 auto [PPR, ZPR] = getSVEStackFrameSizes();
734 SVEStackAllocations SVEAllocs = getSVEStackAllocations({PPR, ZPR});
735
736 MachineBasicBlock::iterator FirstGPRSaveI = PrologueBeginI;
738 assert(!SVEAllocs.AfterPPRs &&
739 "unexpected SVE allocs after PPRs with CalleeSavesAboveFrameRecord");
740 // If we're doing SVE saves first, we need to immediately allocate space
741 // for fixed objects, then space for the SVE callee saves.
742 //
743 // Windows unwind requires that the scalable size is a multiple of 16;
744 // that's handled when the callee-saved size is computed.
745 auto SaveSize = SVEAllocs.BeforePPRs + StackOffset::getFixed(FixedObject);
746 allocateStackSpace(PrologueBeginI, 0, SaveSize, false, StackOffset{},
747 /*FollowupAllocs=*/true);
748 NumBytes -= FixedObject;
749
750 // Now allocate space for the GPR callee saves.
751 MachineBasicBlock::iterator MBBI = PrologueBeginI;
752 while (MBBI != EndI && isPartOfSVECalleeSaves(MBBI))
753 ++MBBI;
755 MBBI, DL, -AFI->getCalleeSavedStackSize(), EmitAsyncCFI);
756 NumBytes -= AFI->getCalleeSavedStackSize();
757 } else if (CombineSPBump) {
758 assert(!AFL.getSVEStackSize(MF) && "Cannot combine SP bump with SVE");
759 emitFrameOffset(MBB, PrologueBeginI, DL, AArch64::SP, AArch64::SP,
760 StackOffset::getFixed(-NumBytes), TII,
762 EmitAsyncCFI);
763 NumBytes = 0;
764 } else if (HomPrologEpilog) {
765 // Stack has been already adjusted.
766 NumBytes -= PrologueSaveSize;
767 } else if (PrologueSaveSize != 0) {
769 PrologueBeginI, DL, -PrologueSaveSize, EmitAsyncCFI);
770 NumBytes -= PrologueSaveSize;
771 }
772 assert(NumBytes >= 0 && "Negative stack allocation size!?");
773
774 // Move past the saves of the callee-saved registers, fixing up the offsets
775 // and pre-inc if we decided to combine the callee-save and local stack
776 // pointer bump above.
777 auto &TLI = *Subtarget.getTargetLowering();
778
779 MachineBasicBlock::iterator AfterGPRSavesI = FirstGPRSaveI;
780 while (AfterGPRSavesI != EndI &&
781 AfterGPRSavesI->getFlag(MachineInstr::FrameSetup) &&
782 !isPartOfSVECalleeSaves(AfterGPRSavesI)) {
783 if (CombineSPBump &&
784 // Only fix-up frame-setup load/store instructions.
785 (!AFL.requiresSaveVG(MF) || !isVGInstruction(AfterGPRSavesI, TLI)))
786 fixupCalleeSaveRestoreStackOffset(*AfterGPRSavesI,
787 AFI->getLocalStackSize());
788 ++AfterGPRSavesI;
789 }
790
791 // For funclets the FP belongs to the containing function. Only set up FP if
792 // we actually need to.
793 if (!IsFunclet && HasFP)
794 emitFramePointerSetup(AfterGPRSavesI, DL, FixedObject);
795
796 // Now emit the moves for whatever callee saved regs we have (including FP,
797 // LR if those are saved). Frame instructions for SVE register are emitted
798 // later, after the instruction which actually save SVE regs.
799 if (EmitAsyncCFI)
800 emitCalleeSavedGPRLocations(AfterGPRSavesI);
801
802 // Alignment is required for the parent frame, not the funclet
803 const bool NeedsRealignment =
804 NumBytes && !IsFunclet && RegInfo.hasStackRealignment(MF);
805 const int64_t RealignmentPadding =
806 (NeedsRealignment && MFI.getMaxAlign() > Align(16))
807 ? MFI.getMaxAlign().value() - 16
808 : 0;
809
810 if (AFL.windowsRequiresStackProbe(MF, NumBytes + RealignmentPadding))
811 emitWindowsStackProbe(AfterGPRSavesI, DL, NumBytes, RealignmentPadding);
812
813 StackOffset NonSVELocalsSize = StackOffset::getFixed(NumBytes);
814 SVEAllocs.AfterZPRs += NonSVELocalsSize;
815
816 StackOffset CFAOffset =
817 StackOffset::getFixed(MFI.getStackSize()) - NonSVELocalsSize;
818 MachineBasicBlock::iterator AfterSVESavesI = AfterGPRSavesI;
819 // Allocate space for the callee saves and PPR locals (if any).
821 auto [PPRRange, ZPRRange] =
822 partitionSVECS(MBB, AfterGPRSavesI, PPR.CalleeSavesSize,
823 ZPR.CalleeSavesSize, /*IsEpilogue=*/false);
824 AfterSVESavesI = ZPRRange.End;
825 if (EmitAsyncCFI)
826 emitCalleeSavedSVELocations(AfterSVESavesI);
827
828 allocateStackSpace(PPRRange.Begin, 0, SVEAllocs.BeforePPRs,
829 EmitAsyncCFI && !HasFP, CFAOffset,
830 MFI.hasVarSizedObjects() || SVEAllocs.AfterPPRs ||
831 SVEAllocs.AfterZPRs);
832 CFAOffset += SVEAllocs.BeforePPRs;
833 assert(PPRRange.End == ZPRRange.Begin &&
834 "Expected ZPR callee saves after PPR locals");
835 allocateStackSpace(PPRRange.End, 0, SVEAllocs.AfterPPRs,
836 EmitAsyncCFI && !HasFP, CFAOffset,
837 MFI.hasVarSizedObjects() || SVEAllocs.AfterZPRs);
838 CFAOffset += SVEAllocs.AfterPPRs;
839 } else {
841 // Note: With CalleeSavesAboveFrameRecord, the SVE CS (BeforePPRs) have
842 // already been allocated. PPR locals (included in AfterPPRs) are not
843 // supported (note: this is asserted above).
844 CFAOffset += SVEAllocs.BeforePPRs;
845 }
846
847 // Allocate space for the rest of the frame including ZPR locals. Align the
848 // stack as necessary.
849 assert(!(AFL.canUseRedZone(MF) && NeedsRealignment) &&
850 "Cannot use redzone with stack realignment");
851 if (!AFL.canUseRedZone(MF)) {
852 // FIXME: in the case of dynamic re-alignment, NumBytes doesn't have the
853 // correct value here, as NumBytes also includes padding bytes, which
854 // shouldn't be counted here.
855 allocateStackSpace(AfterSVESavesI, RealignmentPadding, SVEAllocs.AfterZPRs,
856 EmitAsyncCFI && !HasFP, CFAOffset,
857 MFI.hasVarSizedObjects());
858 }
859
860 // If we need a base pointer, set it up here. It's whatever the value of the
861 // stack pointer is at this point. Any variable size objects will be
862 // allocated after this, so we can still use the base pointer to reference
863 // locals.
864 //
865 // FIXME: Clarify FrameSetup flags here.
866 // Note: Use emitFrameOffset() like above for FP if the FrameSetup flag is
867 // needed.
868 // For funclets the BP belongs to the containing function.
869 if (!IsFunclet && RegInfo.hasBasePointer(MF)) {
870 TII->copyPhysReg(MBB, AfterSVESavesI, DL, RegInfo.getBaseRegister(),
871 AArch64::SP, false);
872 if (NeedsWinCFI) {
873 HasWinCFI = true;
874 BuildMI(MBB, AfterSVESavesI, DL, TII->get(AArch64::SEH_Nop))
876 }
877 }
878
879 // The very last FrameSetup instruction indicates the end of prologue. Emit a
880 // SEH opcode indicating the prologue end.
881 if (NeedsWinCFI && HasWinCFI) {
882 BuildMI(MBB, AfterSVESavesI, DL, TII->get(AArch64::SEH_PrologEnd))
884 }
885
886 // SEH funclets are passed the frame pointer in X1. If the parent
887 // function uses the base register, then the base register is used
888 // directly, and is not retrieved from X1.
889 if (IsFunclet && F.hasPersonalityFn()) {
890 EHPersonality Per = classifyEHPersonality(F.getPersonalityFn());
892 BuildMI(MBB, AfterSVESavesI, DL, TII->get(TargetOpcode::COPY),
893 AArch64::FP)
894 .addReg(AArch64::X1)
896 MBB.addLiveIn(AArch64::X1);
897 }
898 }
899
900 if (EmitCFI && !EmitAsyncCFI) {
901 if (HasFP) {
902 emitDefineCFAWithFP(AfterSVESavesI, FixedObject);
903 } else {
904 StackOffset TotalSize =
905 AFL.getSVEStackSize(MF) +
906 StackOffset::getFixed((int64_t)MFI.getStackSize());
907 CFIInstBuilder CFIBuilder(MBB, AfterSVESavesI, MachineInstr::FrameSetup);
908 CFIBuilder.insertCFIInst(
909 createDefCFA(RegInfo, /*FrameReg=*/AArch64::SP, /*Reg=*/AArch64::SP,
910 TotalSize, /*LastAdjustmentWasScalable=*/false));
911 }
912 emitCalleeSavedGPRLocations(AfterSVESavesI);
913 emitCalleeSavedSVELocations(AfterSVESavesI);
914 }
915}
916
917void AArch64PrologueEmitter::emitShadowCallStackPrologue(
919 // Shadow call stack prolog: str x30, [x18], #8
920 BuildMI(MBB, MBBI, DL, TII->get(AArch64::STRXpost))
921 .addReg(AArch64::X18, RegState::Define)
922 .addReg(AArch64::LR)
923 .addReg(AArch64::X18)
924 .addImm(8)
926
927 // This instruction also makes x18 live-in to the entry block.
928 MBB.addLiveIn(AArch64::X18);
929
930 if (NeedsWinCFI)
931 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
933
934 if (EmitCFI) {
935 // Emit a CFI instruction that causes 8 to be subtracted from the value of
936 // x18 when unwinding past this frame.
937 static const char CFIInst[] = {
938 dwarf::DW_CFA_val_expression,
939 18, // register
940 2, // length
941 static_cast<char>(unsigned(dwarf::DW_OP_breg18)),
942 static_cast<char>(-8) & 0x7f, // addend (sleb128)
943 };
944 CFIInstBuilder(MBB, MBBI, MachineInstr::FrameSetup)
945 .buildEscape(StringRef(CFIInst, sizeof(CFIInst)));
946 }
947}
948
949void AArch64PrologueEmitter::emitSwiftAsyncContextFramePointer(
951 switch (MF.getTarget().Options.SwiftAsyncFramePointer) {
953 if (Subtarget.swiftAsyncContextIsDynamicallySet()) {
954 // The special symbol below is absolute and has a *value* that can be
955 // combined with the frame pointer to signal an extended frame.
956 BuildMI(MBB, MBBI, DL, TII->get(AArch64::LOADgot), AArch64::X16)
957 .addExternalSymbol("swift_async_extendedFramePointerFlags",
959 if (NeedsWinCFI) {
960 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
962 HasWinCFI = true;
963 }
964 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::FP)
965 .addUse(AArch64::FP)
966 .addUse(AArch64::X16)
967 .addImm(Subtarget.isTargetILP32() ? 32 : 0);
968 if (NeedsWinCFI) {
969 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
971 HasWinCFI = true;
972 }
973 break;
974 }
975 [[fallthrough]];
976
978 // ORR x29, x29, #0x1000_0000_0000_0000
979 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXri), AArch64::FP)
980 .addUse(AArch64::FP)
981 .addImm(0x1100)
983 if (NeedsWinCFI) {
984 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
986 HasWinCFI = true;
987 }
988 break;
989
991 break;
992 }
993}
994
995void AArch64PrologueEmitter::emitEmptyStackFramePrologue(
996 int64_t NumBytes, MachineBasicBlock::iterator MBBI,
997 const DebugLoc &DL) const {
998 assert(!HasFP && "unexpected function without stack frame but with FP");
999 assert(!AFL.getSVEStackSize(MF) &&
1000 "unexpected function without stack frame but with SVE objects");
1001 // All of the stack allocation is for locals.
1002 AFI->setLocalStackSize(NumBytes);
1003 if (!NumBytes) {
1004 if (NeedsWinCFI && HasWinCFI) {
1005 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
1007 }
1008 return;
1009 }
1010 // REDZONE: If the stack size is less than 128 bytes, we don't need
1011 // to actually allocate.
1012 if (AFL.canUseRedZone(MF)) {
1013 AFI->setHasRedZone(true);
1014 ++NumRedZoneFunctions;
1015 } else {
1016 emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
1017 StackOffset::getFixed(-NumBytes), TII,
1019 if (EmitCFI) {
1020 // Label used to tie together the PROLOG_LABEL and the MachineMoves.
1021 MCSymbol *FrameLabel = MF.getContext().createTempSymbol();
1022 // Encode the stack size of the leaf function.
1023 CFIInstBuilder(MBB, MBBI, MachineInstr::FrameSetup)
1024 .buildDefCFAOffset(NumBytes, FrameLabel);
1025 }
1026 }
1027
1028 if (NeedsWinCFI) {
1029 HasWinCFI = true;
1030 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
1032 }
1033}
1034
1035void AArch64PrologueEmitter::emitFramePointerSetup(
1037 unsigned FixedObject) {
1038 int64_t FPOffset = AFI->getCalleeSaveBaseToFrameRecordOffset();
1039 if (CombineSPBump)
1040 FPOffset += AFI->getLocalStackSize();
1041
1042 if (AFI->hasSwiftAsyncContext()) {
1043 // Before we update the live FP we have to ensure there's a valid (or
1044 // null) asynchronous context in its slot just before FP in the frame
1045 // record, so store it now.
1046 const auto &Attrs = MF.getFunction().getAttributes();
1047 bool HaveInitialContext = Attrs.hasAttrSomewhere(Attribute::SwiftAsync);
1048 if (HaveInitialContext)
1049 MBB.addLiveIn(AArch64::X22);
1050 Register Reg = HaveInitialContext ? AArch64::X22 : AArch64::XZR;
1051 BuildMI(MBB, MBBI, DL, TII->get(AArch64::StoreSwiftAsyncContext))
1052 .addUse(Reg)
1053 .addUse(AArch64::SP)
1054 .addImm(FPOffset - 8)
1056 if (NeedsWinCFI) {
1057 // WinCFI and arm64e, where StoreSwiftAsyncContext is expanded
1058 // to multiple instructions, should be mutually-exclusive.
1059 assert(Subtarget.getTargetTriple().getArchName() != "arm64e");
1060 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1062 HasWinCFI = true;
1063 }
1064 }
1065
1066 if (HomPrologEpilog) {
1067 auto Prolog = MBBI;
1068 --Prolog;
1069 assert(Prolog->getOpcode() == AArch64::HOM_Prolog);
1070 Prolog->addOperand(MachineOperand::CreateImm(FPOffset));
1071 } else {
1072 // Issue sub fp, sp, FPOffset or
1073 // mov fp,sp when FPOffset is zero.
1074 // Note: All stores of callee-saved registers are marked as "FrameSetup".
1075 // This code marks the instruction(s) that set the FP also.
1076 emitFrameOffset(MBB, MBBI, DL, AArch64::FP, AArch64::SP,
1077 StackOffset::getFixed(FPOffset), TII,
1079 if (NeedsWinCFI && HasWinCFI) {
1080 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
1082 // After setting up the FP, the rest of the prolog doesn't need to be
1083 // included in the SEH unwind info.
1084 NeedsWinCFI = false;
1085 }
1086 }
1087 if (EmitAsyncCFI)
1088 emitDefineCFAWithFP(MBBI, FixedObject);
1089}
1090
1091// Define the current CFA rule to use the provided FP.
1092void AArch64PrologueEmitter::emitDefineCFAWithFP(
1093 MachineBasicBlock::iterator MBBI, unsigned FixedObject) const {
1094 const int OffsetToFirstCalleeSaveFromFP =
1095 AFI->getCalleeSaveBaseToFrameRecordOffset() -
1096 AFI->getCalleeSavedStackSize();
1097 Register FramePtr = RegInfo.getFrameRegister(MF);
1098 CFIInstBuilder(MBB, MBBI, MachineInstr::FrameSetup)
1099 .buildDefCFA(FramePtr, FixedObject - OffsetToFirstCalleeSaveFromFP);
1100}
1101
1102void AArch64PrologueEmitter::emitWindowsStackProbe(
1103 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, int64_t &NumBytes,
1104 int64_t RealignmentPadding) const {
1105 if (AFI->getSVECalleeSavedStackSize())
1106 report_fatal_error("SVE callee saves not yet supported with stack probing");
1107
1108 // Find an available register to spill the value of X15 to, if X15 is being
1109 // used already for nest.
1110 Register X15Scratch;
1111 if (llvm::any_of(MBB.liveins(),
1112 [this](const MachineBasicBlock::RegisterMaskPair &LiveIn) {
1113 return RegInfo.isSuperOrSubRegisterEq(AArch64::X15,
1114 LiveIn.PhysReg);
1115 })) {
1116 X15Scratch = AFL.findScratchNonCalleeSaveRegister(&MBB, /*HasCall=*/true);
1117 assert(X15Scratch.isValid() &&
1118 (X15Scratch < AArch64::X15 || X15Scratch > AArch64::X17));
1119#ifndef NDEBUG
1120 LiveRegs.removeReg(AArch64::X15); // ignore X15 since we restore it
1121#endif
1122 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrr), X15Scratch)
1123 .addReg(AArch64::XZR)
1124 .addReg(AArch64::X15, RegState::Undef)
1125 .addReg(AArch64::X15, RegState::Implicit)
1127 }
1128
1129 uint64_t NumWords = (NumBytes + RealignmentPadding) >> 4;
1130 if (NeedsWinCFI) {
1131 HasWinCFI = true;
1132 // alloc_l can hold at most 256MB, so assume that NumBytes doesn't
1133 // exceed this amount. We need to move at most 2^24 - 1 into x15.
1134 // This is at most two instructions, MOVZ followed by MOVK.
1135 // TODO: Fix to use multiple stack alloc unwind codes for stacks
1136 // exceeding 256MB in size.
1137 if (NumBytes >= (1 << 28))
1138 report_fatal_error("Stack size cannot exceed 256MB for stack "
1139 "unwinding purposes");
1140
1141 uint32_t LowNumWords = NumWords & 0xFFFF;
1142 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVZXi), AArch64::X15)
1143 .addImm(LowNumWords)
1146 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1148 if ((NumWords & 0xFFFF0000) != 0) {
1149 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVKXi), AArch64::X15)
1150 .addReg(AArch64::X15)
1151 .addImm((NumWords & 0xFFFF0000) >> 16) // High half
1154 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1156 }
1157 } else {
1158 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVi64imm), AArch64::X15)
1159 .addImm(NumWords)
1161 }
1162
1163 const AArch64TargetLowering *TLI = Subtarget.getTargetLowering();
1164 RTLIB::LibcallImpl ChkStkLibcall = TLI->getLibcallImpl(RTLIB::STACK_PROBE);
1165 if (ChkStkLibcall == RTLIB::Unsupported)
1166 reportFatalUsageError("no available implementation of __chkstk");
1167
1168 const char *ChkStk = TLI->getLibcallImplName(ChkStkLibcall).data();
1169 switch (MF.getTarget().getCodeModel()) {
1170 case CodeModel::Tiny:
1171 case CodeModel::Small:
1172 case CodeModel::Medium:
1173 case CodeModel::Kernel:
1174 BuildMI(MBB, MBBI, DL, TII->get(AArch64::BL))
1175 .addExternalSymbol(ChkStk)
1176 .addReg(AArch64::X15, RegState::Implicit)
1177 .addReg(AArch64::X16,
1179 .addReg(AArch64::X17,
1181 .addReg(AArch64::NZCV,
1184 if (NeedsWinCFI) {
1185 HasWinCFI = true;
1186 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1188 }
1189 break;
1190 case CodeModel::Large:
1191 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVaddrEXT))
1192 .addReg(AArch64::X16, RegState::Define)
1193 .addExternalSymbol(ChkStk)
1194 .addExternalSymbol(ChkStk)
1196 if (NeedsWinCFI) {
1197 HasWinCFI = true;
1198 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1200 }
1201
1203 .addReg(AArch64::X16, RegState::Kill)
1205 .addReg(AArch64::X16,
1207 .addReg(AArch64::X17,
1209 .addReg(AArch64::NZCV,
1212 if (NeedsWinCFI) {
1213 HasWinCFI = true;
1214 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1216 }
1217 break;
1218 }
1219
1220 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SUBXrx64), AArch64::SP)
1221 .addReg(AArch64::SP, RegState::Kill)
1222 .addReg(AArch64::X15, RegState::Kill)
1225 if (NeedsWinCFI) {
1226 HasWinCFI = true;
1227 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_StackAlloc))
1228 .addImm(NumBytes)
1230 }
1231 NumBytes = 0;
1232
1233 if (RealignmentPadding > 0) {
1234 if (RealignmentPadding >= 4096) {
1235 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVi64imm))
1236 .addReg(AArch64::X16, RegState::Define)
1237 .addImm(RealignmentPadding)
1239 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXrx64), AArch64::X15)
1240 .addReg(AArch64::SP)
1241 .addReg(AArch64::X16, RegState::Kill)
1244 } else {
1245 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXri), AArch64::X15)
1246 .addReg(AArch64::SP)
1247 .addImm(RealignmentPadding)
1248 .addImm(0)
1250 }
1251
1252 uint64_t AndMask = ~(MFI.getMaxAlign().value() - 1);
1253 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ANDXri), AArch64::SP)
1254 .addReg(AArch64::X15, RegState::Kill)
1256 AFI->setStackRealigned(true);
1257
1258 // No need for SEH instructions here; if we're realigning the stack,
1259 // we've set a frame pointer and already finished the SEH prologue.
1261 }
1262 if (X15Scratch.isValid()) {
1263 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrr), AArch64::X15)
1264 .addReg(AArch64::XZR)
1265 .addReg(X15Scratch, RegState::Undef)
1266 .addReg(X15Scratch, RegState::Implicit)
1268 }
1269}
1270
1271void AArch64PrologueEmitter::emitCalleeSavedGPRLocations(
1273 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
1274 if (CSI.empty())
1275 return;
1276
1277 CFIInstBuilder CFIBuilder(MBB, MBBI, MachineInstr::FrameSetup);
1278 for (const auto &Info : CSI) {
1279 unsigned FrameIdx = Info.getFrameIdx();
1280 if (MFI.hasScalableStackID(FrameIdx))
1281 continue;
1282
1283 assert(!Info.isSpilledToReg() && "Spilling to registers not implemented");
1284 int64_t Offset = MFI.getObjectOffset(FrameIdx) - AFL.getOffsetOfLocalArea();
1285 CFIBuilder.buildOffset(Info.getReg(), Offset);
1286 }
1287}
1288
1289void AArch64PrologueEmitter::emitCalleeSavedSVELocations(
1291 // Add callee saved registers to move list.
1292 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
1293 if (CSI.empty())
1294 return;
1295
1296 CFIInstBuilder CFIBuilder(MBB, MBBI, MachineInstr::FrameSetup);
1297
1298 std::optional<int64_t> IncomingVGOffsetFromDefCFA;
1299 if (AFL.requiresSaveVG(MF)) {
1300 auto IncomingVG = *find_if(
1301 reverse(CSI), [](auto &Info) { return Info.getReg() == AArch64::VG; });
1302 IncomingVGOffsetFromDefCFA = MFI.getObjectOffset(IncomingVG.getFrameIdx()) -
1303 AFL.getOffsetOfLocalArea();
1304 }
1305
1306 StackOffset PPRStackSize = AFL.getPPRStackSize(MF);
1307 for (const auto &Info : CSI) {
1308 int FI = Info.getFrameIdx();
1309 if (!MFI.hasScalableStackID(FI))
1310 continue;
1311
1312 // Not all unwinders may know about SVE registers, so assume the lowest
1313 // common denominator.
1314 assert(!Info.isSpilledToReg() && "Spilling to registers not implemented");
1315 MCRegister Reg = Info.getReg();
1316 if (!RegInfo.regNeedsCFI(Reg, Reg))
1317 continue;
1318
1319 StackOffset Offset =
1320 StackOffset::getScalable(MFI.getObjectOffset(FI)) -
1321 StackOffset::getFixed(AFI->getCalleeSavedStackSize(MFI));
1322
1323 // The scalable vectors are below (lower address) the scalable predicates
1324 // with split SVE objects, so we must subtract the size of the predicates.
1326 MFI.getStackID(FI) == TargetStackID::ScalableVector)
1327 Offset -= PPRStackSize;
1328
1329 CFIBuilder.insertCFIInst(
1330 createCFAOffset(RegInfo, Reg, Offset, IncomingVGOffsetFromDefCFA));
1331 }
1332}
1333
1335 switch (MI.getOpcode()) {
1336 default:
1337 return false;
1338 case AArch64::CATCHRET:
1339 case AArch64::CLEANUPRET:
1340 return true;
1341 }
1342}
1343
1348 EmitCFI = AFI->needsAsyncDwarfUnwindInfo(MF);
1349 HomPrologEpilog = AFL.homogeneousPrologEpilog(MF, &MBB);
1350 SEHEpilogueStartI = MBB.end();
1351}
1352
1353void AArch64EpilogueEmitter::moveSPBelowFP(MachineBasicBlock::iterator MBBI,
1355 // Other combinations could be supported, but are not currently needed.
1356 assert(Offset.getScalable() < 0 && Offset.getFixed() <= 0 &&
1357 "expected negative offset (with optional fixed portion)");
1358 Register Base = AArch64::FP;
1359 if (int64_t FixedOffset = Offset.getFixed()) {
1360 // If we have a negative fixed offset, we need to first subtract it in a
1361 // temporary register first (to avoid briefly deallocating the scalable
1362 // portion of the offset).
1363 Base = MF.getRegInfo().createVirtualRegister(&AArch64::GPR64RegClass);
1364 emitFrameOffset(MBB, MBBI, DL, Base, AArch64::FP,
1365 StackOffset::getFixed(FixedOffset), TII,
1367 }
1368 emitFrameOffset(MBB, MBBI, DL, AArch64::SP, Base,
1369 StackOffset::getScalable(Offset.getScalable()), TII,
1371}
1372
1374 MachineBasicBlock::iterator EpilogueEndI = MBB.getLastNonDebugInstr();
1375 if (MBB.end() != EpilogueEndI) {
1376 DL = EpilogueEndI->getDebugLoc();
1377 IsFunclet = isFuncletReturnInstr(*EpilogueEndI);
1378 }
1379
1380 int64_t NumBytes =
1381 IsFunclet ? AFL.getWinEHFuncletFrameSize(MF) : MFI.getStackSize();
1382
1383 // All calls are tail calls in GHC calling conv, and functions have no
1384 // prologue/epilogue.
1385 if (MF.getFunction().getCallingConv() == CallingConv::GHC)
1386 return;
1387
1388 // How much of the stack used by incoming arguments this function is expected
1389 // to restore in this particular epilogue.
1390 int64_t ArgumentStackToRestore = AFL.getArgumentStackToRestore(MF, MBB);
1391 bool IsWin64 = Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv(),
1392 MF.getFunction().isVarArg());
1393 unsigned FixedObject = AFL.getFixedObjectSize(MF, AFI, IsWin64, IsFunclet);
1394
1395 const bool AuthenticateReturnAddressEarly =
1396 !IsFunclet && AFL.authenticatesReturnAddressEarly(MF, MBB);
1397
1398 int64_t AfterCSRPopSize = ArgumentStackToRestore;
1399 auto PrologueSaveSize = AFI->getCalleeSavedStackSize() + FixedObject;
1400 // We cannot rely on the local stack size set in emitPrologue if the function
1401 // has funclets, as funclets have different local stack size requirements, and
1402 // the current value set in emitPrologue may be that of the containing
1403 // function.
1404 if (MF.hasEHFunclets())
1405 AFI->setLocalStackSize(NumBytes - PrologueSaveSize);
1406
1407 if (HomPrologEpilog) {
1409 auto FirstHomogenousEpilogI = MBB.getFirstTerminator();
1410 if (FirstHomogenousEpilogI != MBB.begin()) {
1411 auto HomogeneousEpilog = std::prev(FirstHomogenousEpilogI);
1412 if (HomogeneousEpilog->getOpcode() == AArch64::HOM_Epilog)
1413 FirstHomogenousEpilogI = HomogeneousEpilog;
1414 }
1415
1416 // Adjust local stack
1417 emitFrameOffset(MBB, FirstHomogenousEpilogI, DL, AArch64::SP, AArch64::SP,
1418 StackOffset::getFixed(AFI->getLocalStackSize()), TII,
1420
1421 // SP has been already adjusted while restoring callee save regs.
1422 // We've bailed-out the case with adjusting SP for arguments.
1423 assert(AfterCSRPopSize == 0);
1424 return;
1425 }
1426
1427 bool CombineSPBump = shouldCombineCSRLocalStackBump(NumBytes);
1428
1429 unsigned ProloguePopSize = PrologueSaveSize;
1431 // With CalleeSavesAboveFrameRecord ProloguePopSize is the amount of stack
1432 // that needs to be popped until we reach the start of the SVE save area.
1433 // The "FixedObject" stack occurs after the SVE area and must be popped
1434 // later.
1435 ProloguePopSize -= FixedObject;
1436 AfterCSRPopSize += FixedObject;
1437 }
1438
1439 // Assume we can't combine the last pop with the sp restore. If the return
1440 // address is authenticated early, it wasn't restored, so the last pop may
1441 // not exist, and in any case the SP adjustment is made explicitly.
1442 if (!CombineSPBump && ProloguePopSize != 0 &&
1443 AuthenticateReturnAddressEarly) {
1444 AfterCSRPopSize += ProloguePopSize;
1445 } else if (!CombineSPBump && ProloguePopSize != 0) {
1446 MachineBasicBlock::iterator Pop = std::prev(MBB.getFirstTerminator());
1447 while (Pop->getOpcode() == TargetOpcode::CFI_INSTRUCTION ||
1448 AArch64InstrInfo::isSEHInstruction(*Pop) ||
1451 Pop = std::prev(Pop);
1452 // Converting the last ldp to a post-index ldp is valid only if the last
1453 // ldp's offset is 0.
1454 const MachineOperand &OffsetOp = Pop->getOperand(Pop->getNumOperands() - 1);
1455 // If the offset is 0 and the AfterCSR pop is not actually trying to
1456 // allocate more stack for arguments (in space that an untimely interrupt
1457 // may clobber), convert it to a post-index ldp.
1458 if (OffsetOp.getImm() == 0 && AfterCSRPopSize >= 0) {
1460 Pop, DL, ProloguePopSize, EmitCFI, MachineInstr::FrameDestroy,
1461 ProloguePopSize);
1463 MachineBasicBlock::iterator AfterLastPop = std::next(Pop);
1464 if (AArch64InstrInfo::isSEHInstruction(*AfterLastPop))
1465 ++AfterLastPop;
1466 // If not, and CalleeSavesAboveFrameRecord is enabled, deallocate
1467 // callee-save non-SVE registers to move the stack pointer to the start of
1468 // the SVE area.
1469 emitFrameOffset(MBB, AfterLastPop, DL, AArch64::SP, AArch64::SP,
1470 StackOffset::getFixed(ProloguePopSize), TII,
1472 &HasWinCFI);
1473 } else {
1474 // Otherwise, make sure to emit an add after the last ldp.
1475 // We're doing this by transferring the size to be restored from the
1476 // adjustment *before* the CSR pops to the adjustment *after* the CSR
1477 // pops.
1478 AfterCSRPopSize += ProloguePopSize;
1479 }
1480 }
1481
1482 // Move past the restores of the callee-saved registers.
1483 // If we plan on combining the sp bump of the local stack size and the callee
1484 // save stack size, we might need to adjust the CSR save and restore offsets.
1485 MachineBasicBlock::iterator FirstGPRRestoreI = MBB.getFirstTerminator();
1486 MachineBasicBlock::iterator Begin = MBB.begin();
1487 while (FirstGPRRestoreI != Begin) {
1488 --FirstGPRRestoreI;
1489 if (!FirstGPRRestoreI->getFlag(MachineInstr::FrameDestroy) ||
1491 isPartOfSVECalleeSaves(FirstGPRRestoreI))) {
1492 ++FirstGPRRestoreI;
1493 break;
1494 } else if (CombineSPBump)
1495 fixupCalleeSaveRestoreStackOffset(*FirstGPRRestoreI,
1496 AFI->getLocalStackSize());
1497 }
1498
1499 // The unwind info can't describe authenticating the return address in an
1500 // epilogue that leaves SP somewhere other than where it was on entry, so do
1501 // it before the epilogue starts instead.
1502 if (AuthenticateReturnAddressEarly)
1503 emitEarlyReturnAddressAuthentication(FirstGPRRestoreI, MFI.getStackSize(),
1504 PrologueSaveSize);
1505
1506 if (NeedsWinCFI) {
1507 // Note that there are cases where we insert SEH opcodes in the
1508 // epilogue when we had no SEH opcodes in the prologue. For
1509 // example, when there is no stack frame but there are stack
1510 // arguments. Insert the SEH_EpilogStart and remove it later if it
1511 // we didn't emit any SEH opcodes to avoid generating WinCFI for
1512 // functions that don't need it.
1513 BuildMI(MBB, FirstGPRRestoreI, DL, TII->get(AArch64::SEH_EpilogStart))
1515 SEHEpilogueStartI = FirstGPRRestoreI;
1516 --SEHEpilogueStartI;
1517 }
1518
1519 // Determine the ranges of SVE callee-saves. This is done before emitting any
1520 // code at the end of the epilogue (for Swift async), which can get in the way
1521 // of finding SVE callee-saves with CalleeSavesAboveFrameRecord.
1522 auto [PPR, ZPR] = getSVEStackFrameSizes();
1523 auto [PPRRange, ZPRRange] = partitionSVECS(
1524 MBB,
1526 ? MBB.getFirstTerminator()
1527 : FirstGPRRestoreI,
1528 PPR.CalleeSavesSize, ZPR.CalleeSavesSize, /*IsEpilogue=*/true);
1529
1530 if (HasFP && AFI->hasSwiftAsyncContext())
1531 emitSwiftAsyncContextFramePointer(EpilogueEndI, DL);
1532
1533 // If there is a single SP update, insert it before the ret and we're done.
1534 if (CombineSPBump) {
1535 assert(!AFI->hasSVEStackSize() && "Cannot combine SP bump with SVE");
1536
1537 // When we are about to restore the CSRs, the CFA register is SP again.
1538 if (EmitCFI && HasFP)
1540 .buildDefCFA(AArch64::SP, NumBytes);
1541
1542 emitFrameOffset(MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP,
1543 StackOffset::getFixed(NumBytes + AfterCSRPopSize), TII,
1545 EmitCFI, StackOffset::getFixed(NumBytes));
1546 return;
1547 }
1548
1549 NumBytes -= PrologueSaveSize;
1550 assert(NumBytes >= 0 && "Negative stack allocation size!?");
1551
1552 StackOffset SVECalleeSavesSize = ZPR.CalleeSavesSize + PPR.CalleeSavesSize;
1553 SVEStackAllocations SVEAllocs = getSVEStackAllocations({PPR, ZPR});
1554
1555 // Deallocate the SVE area.
1557 assert(!SVEAllocs.AfterPPRs &&
1558 "unexpected SVE allocs after PPRs with CalleeSavesAboveFrameRecord");
1559 // If the callee-save area is before FP, restoring the FP implicitly
1560 // deallocates non-callee-save SVE allocations. Otherwise, deallocate them
1561 // explicitly.
1562 if (!AFI->isStackRealigned() && !MFI.hasVarSizedObjects()) {
1563 emitFrameOffset(MBB, FirstGPRRestoreI, DL, AArch64::SP, AArch64::SP,
1565 false, NeedsWinCFI, &HasWinCFI);
1566 }
1567
1568 // Deallocate callee-save SVE registers.
1569 emitFrameOffset(MBB, PPRRange.End, DL, AArch64::SP, AArch64::SP,
1571 false, NeedsWinCFI, &HasWinCFI);
1572 } else if (AFI->hasSVEStackSize()) {
1573 // If we have stack realignment or variable-sized objects we must use the FP
1574 // to restore SVE callee saves (as there is an unknown amount of
1575 // data/padding between the SP and SVE CS area).
1576 Register BaseForSVEDealloc =
1577 (AFI->isStackRealigned() || MFI.hasVarSizedObjects()) ? AArch64::FP
1578 : AArch64::SP;
1579 if (SVECalleeSavesSize && BaseForSVEDealloc == AArch64::FP) {
1580 if (ZPR.CalleeSavesSize || SVELayout != SVEStackLayout::Split) {
1581 // The offset from the frame-pointer to the start of the ZPR saves.
1582 StackOffset FPOffsetZPR =
1583 -SVECalleeSavesSize - PPR.LocalsSize -
1584 StackOffset::getFixed(AFI->getCalleeSaveBaseToFrameRecordOffset());
1585 // Deallocate the stack space space by moving the SP to the start of the
1586 // ZPR/PPR callee-save area.
1587 moveSPBelowFP(ZPRRange.Begin, FPOffsetZPR);
1588 }
1589 // With split SVE, the predicates are stored in a separate area above the
1590 // ZPR saves, so we must adjust the stack to the start of the PPRs.
1591 if (PPR.CalleeSavesSize && SVELayout == SVEStackLayout::Split) {
1592 // The offset from the frame-pointer to the start of the PPR saves.
1593 StackOffset FPOffsetPPR = -PPR.CalleeSavesSize;
1594 // Move to the start of the PPR area.
1595 assert(!FPOffsetPPR.getFixed() && "expected only scalable offset");
1596 emitFrameOffset(MBB, ZPRRange.End, DL, AArch64::SP, AArch64::FP,
1597 FPOffsetPPR, TII, MachineInstr::FrameDestroy);
1598 }
1599 } else if (BaseForSVEDealloc == AArch64::SP) {
1600 auto NonSVELocals = StackOffset::getFixed(NumBytes);
1601 auto CFAOffset = NonSVELocals + StackOffset::getFixed(PrologueSaveSize) +
1602 SVEAllocs.totalSize();
1603
1604 if (SVECalleeSavesSize || SVELayout == SVEStackLayout::Split) {
1605 // Deallocate non-SVE locals now. This is needed to reach the SVE callee
1606 // saves, but may also allow combining stack hazard bumps for split SVE.
1607 SVEAllocs.AfterZPRs += NonSVELocals;
1608 NumBytes -= NonSVELocals.getFixed();
1609 }
1610 // To deallocate the SVE stack adjust by the allocations in reverse.
1611 emitFrameOffset(MBB, ZPRRange.Begin, DL, AArch64::SP, AArch64::SP,
1613 false, NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1614 CFAOffset);
1615 CFAOffset -= SVEAllocs.AfterZPRs;
1616 assert(PPRRange.Begin == ZPRRange.End &&
1617 "Expected PPR restores after ZPR");
1618 emitFrameOffset(MBB, PPRRange.Begin, DL, AArch64::SP, AArch64::SP,
1620 false, NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1621 CFAOffset);
1622 CFAOffset -= SVEAllocs.AfterPPRs;
1623 emitFrameOffset(MBB, PPRRange.End, DL, AArch64::SP, AArch64::SP,
1625 false, NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1626 CFAOffset);
1627 }
1628
1629 if (EmitCFI)
1630 emitCalleeSavedSVERestores(
1631 SVELayout == SVEStackLayout::Split ? ZPRRange.End : PPRRange.End);
1632 }
1633
1634 if (!HasFP) {
1635 bool RedZone = AFL.canUseRedZone(MF);
1636 // If this was a redzone leaf function, we don't need to restore the
1637 // stack pointer (but we may need to pop stack args for fastcc).
1638 if (RedZone && AfterCSRPopSize == 0)
1639 return;
1640
1641 // Pop the local variables off the stack. If there are no callee-saved
1642 // registers, it means we are actually positioned at the terminator and can
1643 // combine stack increment for the locals and the stack increment for
1644 // callee-popped arguments into (possibly) a single instruction and be done.
1645 bool NoCalleeSaveRestore = PrologueSaveSize == 0;
1646 int64_t StackRestoreBytes = RedZone ? 0 : NumBytes;
1647 if (NoCalleeSaveRestore)
1648 StackRestoreBytes += AfterCSRPopSize;
1649
1651 MBB, FirstGPRRestoreI, DL, AArch64::SP, AArch64::SP,
1652 StackOffset::getFixed(StackRestoreBytes), TII,
1654 StackOffset::getFixed((RedZone ? 0 : NumBytes) + PrologueSaveSize));
1655
1656 // If we were able to combine the local stack pop with the argument pop,
1657 // then we're done.
1658 if (NoCalleeSaveRestore || AfterCSRPopSize == 0)
1659 return;
1660
1661 NumBytes = 0;
1662 }
1663
1664 // Restore the original stack pointer.
1665 // FIXME: Rather than doing the math here, we should instead just use
1666 // non-post-indexed loads for the restores if we aren't actually going to
1667 // be able to save any instructions.
1668 if (!IsFunclet && (MFI.hasVarSizedObjects() || AFI->isStackRealigned())) {
1670 MBB, FirstGPRRestoreI, DL, AArch64::SP, AArch64::FP,
1671 StackOffset::getFixed(-AFI->getCalleeSaveBaseToFrameRecordOffset()),
1673 } else if (NumBytes)
1674 emitFrameOffset(MBB, FirstGPRRestoreI, DL, AArch64::SP, AArch64::SP,
1675 StackOffset::getFixed(NumBytes), TII,
1677
1678 // When we are about to restore the CSRs, the CFA register is SP again.
1679 if (EmitCFI && HasFP)
1681 .buildDefCFA(AArch64::SP, PrologueSaveSize);
1682
1683 // This must be placed after the callee-save restore code because that code
1684 // assumes the SP is at the same location as it was after the callee-save save
1685 // code in the prologue.
1686 if (AfterCSRPopSize) {
1687 assert(AfterCSRPopSize > 0 && "attempting to reallocate arg stack that an "
1688 "interrupt may have clobbered");
1689
1691 MBB, MBB.getFirstTerminator(), DL, AArch64::SP, AArch64::SP,
1693 false, NeedsWinCFI, &HasWinCFI, EmitCFI,
1694 StackOffset::getFixed(AfterCSRPopSize - ArgumentStackToRestore));
1695 }
1696}
1697
1698bool AArch64EpilogueEmitter::shouldCombineCSRLocalStackBump(
1699 uint64_t StackBumpBytes) const {
1701 StackBumpBytes))
1702 return false;
1703 if (MBB.empty())
1704 return true;
1705
1706 // Disable combined SP bump if the last instruction is an MTE tag store. It
1707 // is almost always better to merge SP adjustment into those instructions.
1708 MachineBasicBlock::iterator LastI = MBB.getFirstTerminator();
1709 MachineBasicBlock::iterator Begin = MBB.begin();
1710 while (LastI != Begin) {
1711 --LastI;
1712 if (LastI->isTransient())
1713 continue;
1714 if (!LastI->getFlag(MachineInstr::FrameDestroy))
1715 break;
1716 }
1717 switch (LastI->getOpcode()) {
1718 case AArch64::STGloop:
1719 case AArch64::STZGloop:
1720 case AArch64::STGi:
1721 case AArch64::STZGi:
1722 case AArch64::ST2Gi:
1723 case AArch64::STZ2Gi:
1724 return false;
1725 default:
1726 return true;
1727 }
1728 llvm_unreachable("unreachable");
1729}
1730
1731void AArch64EpilogueEmitter::emitSwiftAsyncContextFramePointer(
1733 switch (MF.getTarget().Options.SwiftAsyncFramePointer) {
1735 // Avoid the reload as it is GOT relative, and instead fall back to the
1736 // hardcoded value below. This allows a mismatch between the OS and
1737 // application without immediately terminating on the difference.
1738 [[fallthrough]];
1740 // We need to reset FP to its untagged state on return. Bit 60 is
1741 // currently used to show the presence of an extended frame.
1742
1743 // BIC x29, x29, #0x1000_0000_0000_0000
1744 BuildMI(MBB, MBB.getFirstTerminator(), DL, TII->get(AArch64::ANDXri),
1745 AArch64::FP)
1746 .addUse(AArch64::FP)
1747 .addImm(0x10fe)
1749 if (NeedsWinCFI) {
1750 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1752 HasWinCFI = true;
1753 }
1754 break;
1755
1757 break;
1758 }
1759}
1760
1761void AArch64EpilogueEmitter::emitShadowCallStackEpilogue(
1763 // Shadow call stack epilog: ldr x30, [x18, #-8]!
1764 BuildMI(MBB, MBBI, DL, TII->get(AArch64::LDRXpre))
1765 .addReg(AArch64::X18, RegState::Define)
1766 .addReg(AArch64::LR, RegState::Define)
1767 .addReg(AArch64::X18)
1768 .addImm(-8)
1770
1771 if (NeedsWinCFI)
1772 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop))
1774
1775 if (AFI->needsAsyncDwarfUnwindInfo(MF))
1776 CFIInstBuilder(MBB, MBBI, MachineInstr::FrameDestroy)
1777 .buildRestore(AArch64::X18);
1778}
1779
1780void AArch64EpilogueEmitter::emitEarlyReturnAddressAuthentication(
1781 MachineBasicBlock::iterator MBBI, int64_t StackSize,
1782 int64_t PrologueSaveSize) {
1783 // Windows unwind info describes authenticating the return address with a
1784 // pac_sign_lr unwind code, which the unwinder applies using the SP it has at
1785 // that point; that is only the SP the return address was signed with if the
1786 // epilogue ends with SP back at its entry value. When it doesn't, we
1787 // authenticate the return address here instead, in the body, where the
1788 // prologue's unwind codes apply and the return address is still signed. The
1789 // epilogue's unwind codes then have no pac_sign_lr, and nor do they restore
1790 // LR: the authenticated return address stays in LR (it is never written back
1791 // to the stack) and the epilogue doesn't reload it. There is no window in
1792 // which the unwinder sees the wrong state: this sequence is immediately
1793 // before the start of the epilogue, so the prologue's codes apply to every
1794 // instruction up to and including the last of it, which recover the signed
1795 // return address from its slot on the stack, and the epilogue's apply after.
1796 if (AFI->hasSVEStackSize())
1797 report_fatal_error("Can't handle a tail call that changes the stack "
1798 "argument size in a function with SVE stack objects "
1799 "that signs its return address on Windows");
1800
1801 // The return address is only on the stack if it was spilled.
1802 std::optional<int> LRFrameIdx;
1803 for (const CalleeSavedInfo &CSI : MFI.getCalleeSavedInfo())
1804 if (CSI.getReg() == AArch64::LR)
1805 LRFrameIdx = CSI.getFrameIdx();
1806
1807 // When the frame is addressed via the FP, the return address is in the frame
1808 // record, at FP + 8. We don't refer to its frame index there because the SP
1809 // is not reliable as a base, and the frame index of a callee-saved register
1810 // isn't always recognised as one on Windows when there is a tail call
1811 // reserve.
1812 bool UseFP = MFI.hasVarSizedObjects() || AFI->isStackRealigned();
1813
1814 // Compute the SP the return address was signed with, which is SP on entry.
1815 int64_t Adjustment =
1816 UseFP ? PrologueSaveSize - AFI->getCalleeSaveBaseToFrameRecordOffset()
1817 : StackSize;
1819 MBB, MBBI, DL, AArch64::X16, UseFP ? AArch64::FP : AArch64::SP,
1821
1822 // LR holds whatever the last call left in it; get the signed return address.
1823 // The authentication sequence expects it in X17 if it works on that and moves
1824 // the result to LR, which saves a copy.
1826 AFI->branchProtectionPAuthLR(), Subtarget.hasPAuth());
1827 Register SignedLR = InX17 ? Register(AArch64::X17) : Register(AArch64::LR);
1828 if (LRFrameIdx) {
1829 MachineInstrBuilder MIB =
1830 BuildMI(MBB, MBBI, DL, TII->get(AArch64::LDRXui), SignedLR);
1831 if (UseFP)
1832 MIB.addReg(AArch64::FP).addImm(1);
1833 else
1834 MIB.addFrameIndex(*LRFrameIdx).addImm(0);
1835 MIB.addMemOperand(MF.getMachineMemOperand(
1838 } else if (InX17) {
1839 // The return address was never spilled, so it is still in LR.
1840 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::X17)
1841 .addReg(AArch64::XZR)
1842 .addReg(AArch64::LR)
1843 .addImm(0);
1844 }
1845
1846 auto Builder =
1847 BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_EPILOGUE_ENTRY_SP));
1848 Builder.addReg(AArch64::X16, RegState::Implicit);
1849 if (InX17) {
1850 Builder.addReg(AArch64::X17, RegState::Implicit);
1851 // The pseudo's implicit use of LR is not a real one here; the signed return
1852 // address is in X17, and LR only gets written.
1853 Builder->findRegisterUseOperand(AArch64::LR, &RegInfo)->setIsUndef();
1854 }
1855 Builder.addReg(AArch64::X17, RegState::ImplicitDefine);
1856 if (AFI->branchProtectionPAuthLR())
1857 Builder.addReg(AArch64::X15, RegState::ImplicitDefine);
1858
1859 // This takes the place of the pseudo that would otherwise go at the end.
1860 for (MachineInstr &MI : llvm::make_early_inc_range(MBB))
1861 if (MI.getOpcode() == AArch64::PAUTH_EPILOGUE)
1862 MI.eraseFromParent();
1863 AuthenticatedReturnAddressEarly = true;
1864}
1865
1866void AArch64EpilogueEmitter::emitCalleeSavedRestores(
1867 MachineBasicBlock::iterator MBBI, bool SVE) const {
1868 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
1869 if (CSI.empty())
1870 return;
1871
1872 CFIInstBuilder CFIBuilder(MBB, MBBI, MachineInstr::FrameDestroy);
1873
1874 for (const auto &Info : CSI) {
1875 if (SVE != MFI.hasScalableStackID(Info.getFrameIdx()))
1876 continue;
1877
1878 MCRegister Reg = Info.getReg();
1879 if (SVE && !RegInfo.regNeedsCFI(Reg, Reg))
1880 continue;
1881
1882 CFIBuilder.buildRestore(Info.getReg());
1883 }
1884}
1885
1886bool AArch64EpilogueEmitter::hasEpilogueUnwindOps() const {
1887 // The return address is authenticated by an unwind op that the
1888 // AArch64PointerAuth pass adds later, or, if it was authenticated early, the
1889 // epilogue's unwind codes are what keep the prologue's pac_sign_lr from being
1890 // applied again, even if there is nothing else in them.
1891 if (AFI->shouldSignReturnAddress(MF))
1892 return true;
1893 return std::any_of(std::next(SEHEpilogueStartI), MBB.end(),
1894 [](const MachineInstr &MI) {
1895 return AArch64InstrInfo::isSEHInstruction(MI) &&
1896 MI.getOpcode() != AArch64::SEH_EpilogEnd;
1897 });
1898}
1899
1900void AArch64EpilogueEmitter::finalizeEpilogue() const {
1901 // All calls are tail calls in GHC calling conv, and functions have no
1902 // prologue/epilogue.
1903 if (MF.getFunction().getCallingConv() == CallingConv::GHC)
1904 return;
1905
1906 if (AFI->needsShadowCallStackPrologueEpilogue(MF)) {
1907 emitShadowCallStackEpilogue(MBB.getFirstTerminator(), DL);
1909 }
1910 if (EmitCFI)
1911 emitCalleeSavedGPRRestores(MBB.getFirstTerminator());
1912 if (AFI->shouldSignReturnAddress(MF)) {
1913 // If pac-ret+leaf is in effect, PAUTH_EPILOGUE pseudo instructions
1914 // are inserted by emitPacRetPlusLeafHardening().
1915 if (!AFL.shouldSignReturnAddressEverywhere(MF) &&
1916 !AuthenticatedReturnAddressEarly)
1917 TII->createPauthEpilogueInstr(MBB, DL);
1918 // AArch64PointerAuth pass will insert SEH_PACSignLR, unless the return
1919 // address was authenticated early (see
1920 // emitEarlyReturnAddressAuthentication()).
1922 }
1923 // A tail call leaves the stack arguments for the tail callee, which pops them
1924 // itself. Until then the unwinder must pop them to recover the caller's SP,
1925 // as in the prologue; there is no instruction to describe that, so it goes
1926 // after end_c. An epilogue with no unwind ops of its own gains nothing from
1927 // this, as the prologue's codes cover it.
1928 if (NeedsWinCFI && HasWinCFI && !IsFunclet && hasEpilogueUnwindOps()) {
1929 int64_t TailCalleePopBytes = AFI->getArgumentStackToRestore() -
1930 AFL.getArgumentStackToRestore(MF, MBB);
1931 if (TailCalleePopBytes > 0) {
1932 BuildMI(MBB, MBB.getFirstTerminator(), DL, TII->get(AArch64::SEH_EndC))
1934 BuildMI(MBB, MBB.getFirstTerminator(), DL,
1935 TII->get(AArch64::SEH_StackAlloc))
1936 .addImm(TailCalleePopBytes)
1938 HasWinCFI = true;
1939 }
1940 }
1941 if (HasWinCFI) {
1942 BuildMI(MBB, MBB.getFirstTerminator(), DL, TII->get(AArch64::SEH_EpilogEnd))
1944 if (!MF.hasWinCFI())
1945 MF.setHasWinCFI(true);
1946 }
1947 if (NeedsWinCFI) {
1948 assert(SEHEpilogueStartI != MBB.end());
1949 if (!HasWinCFI)
1950 MBB.erase(SEHEpilogueStartI);
1951 }
1952}
1953
1954} // namespace llvm
const AArch64Subtarget & Subtarget
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declaration of the AArch64PrologueEmitter and AArch64EpilogueEmitter classes,...
uint64_t uint64_t
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains constants used for implementing Dwarf debug support.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
if(PassOpts->AAPipeline)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
static Function * getFunction(FunctionType *Ty, const Twine &Name, Module *M)
static const unsigned FramePtr
AArch64EpilogueEmitter(MachineFunction &MF, MachineBasicBlock &MBB, const AArch64FrameLowering &AFL)
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
AArch64PrologueEmitter(MachineFunction &MF, MachineBasicBlock &MBB, const AArch64FrameLowering &AFL)
MachineBasicBlock::iterator convertCalleeSaveRestoreToSPPrePostIncDec(MachineBasicBlock::iterator MBBI, const DebugLoc &DL, int CSStackSizeInc, bool EmitCFI, MachineInstr::MIFlag FrameFlag=MachineInstr::FrameSetup, int CFAOffset=0) const
bool isVGInstruction(MachineBasicBlock::iterator MBBI, const TargetLowering &TLI) const
AArch64PrologueEpilogueCommon(MachineFunction &MF, MachineBasicBlock &MBB, const AArch64FrameLowering &AFL)
void fixupCalleeSaveRestoreStackOffset(MachineInstr &MI, uint64_t LocalStackSize) const
bool shouldCombineCSRLocalStackBump(uint64_t StackBumpBytes) const
SVEStackAllocations getSVEStackAllocations(SVEFrameSizes const &)
Helper class for creating CFI instructions and inserting them into MIR.
void buildDefCFAOffset(int64_t Offset, MCSymbol *Label=nullptr) const
void insertCFIInst(const MCCFIInstruction &CFIInst) const
void buildDefCFA(MCRegister Reg, int64_t Offset) const
A debug info location.
Definition DebugLoc.h:126
A set of physical registers with utility functions to track liveness when walking backward/forward th...
MachineInstrBundleIterator< MachineInstr > iterator
Align getMaxAlign() const
Return alignment of this function's frame.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
MachineOperand class - Representation of each machine instruction operand.
void setImm(int64_t immVal)
int64_t getImm() const
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
static MachineOperand CreateImm(int64_t Val)
const char * getSymbolName() const
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:31
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:47
int64_t getScalable() const
Returns the scalable component of the stack.
Definition TypeSize.h:50
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:40
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:352
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
constexpr bool authenticatesLRViaX17(bool BranchProtectionPAuthLR, bool HasPAuth)
Controls whether, for PAUTH_EPILOGUE_ENTRY_SP, we use the hint-space AUTI[AB]1716 instruction to auth...
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
const unsigned StackProbeMaxUnprobedStack
Maximum allowed number of unprobed bytes above SP at an ABI boundary.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
Definition CallingConv.h:50
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
MCCFIInstruction createDefCFA(const TargetRegisterInfo &TRI, unsigned FrameReg, unsigned Reg, const StackOffset &Offset, bool LastAdjustmentWasScalable=true)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Dead
Unused definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ Define
Register definition.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
unsigned getBLRCallOpcode(const MachineFunction &MF)
Return opcode to be used for indirect calls.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
static bool matchLibcall(const TargetLowering &TLI, const MachineOperand &MO, RTLIB::Libcall LC)
static bool isPartOfSVECalleeSaves(MachineBasicBlock::iterator I)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
static bool isFuncletReturnInstr(const MachineInstr &MI)
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
static void getLivePhysRegsUpTo(MachineInstr &MI, const TargetRegisterInfo &TRI, LivePhysRegs &LiveRegs)
Collect live registers from the end of MI's parent up to (including) MI in LiveRegs.
@ DeploymentBased
Determine whether to set the bit statically or dynamically based on the deployment target.
void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, StackOffset Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag=MachineInstr::NoFlags, bool SetNZCV=false, bool NeedsWinCFI=false, bool *HasWinCFI=nullptr, bool EmitCFAOffset=false, StackOffset InitialOffset={}, unsigned FrameReg=AArch64::SP)
emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg plus Offset.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
static bool isPartOfPPRCalleeSaves(MachineBasicBlock::iterator I)
@ Success
The lock was released successfully.
static void fixupSEHOpcode(MachineBasicBlock::iterator MBBI, unsigned LocalStackSize)
MCCFIInstruction createCFAOffset(const TargetRegisterInfo &MRI, unsigned Reg, const StackOffset &OffsetFromDefCFA, std::optional< int64_t > IncomingVGOffsetFromDefCFA)
DWARFExpression::Operation Op
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
static SVEPartitions partitionSVECS(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, StackOffset PPRCalleeSavesSize, StackOffset ZPRCalleeSavesSize, bool IsEpilogue)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
static bool isPartOfZPRCalleeSaves(MachineBasicBlock::iterator I)
static int64_t upperBound(StackOffset Size)
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:82
static LLVM_ABI MachinePointerInfo getUnknownStack(MachineFunction &MF)
Stack memory without other information.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
MachineBasicBlock::iterator End
struct llvm::SVEPartitions::@327166152017175235362202041204223104077330276266 ZPR
struct llvm::SVEPartitions::@327166152017175235362202041204223104077330276266 PPR
MachineBasicBlock::iterator Begin