@@ -2537,7 +2537,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2537
2537
} else if (SVEStackSize) {
2538
2538
const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo ();
2539
2539
int64_t SVECalleeSavedSize = AFI->getSVECalleeSavedStackSize ();
2540
- Register BaseForSVERestore = [&]() -> Register {
2540
+ Register BaseForSVEDealloc = [&]() -> Register {
2541
2541
// With stack realignment we must use the FP to restore SVE CSRs (as both
2542
2542
// the SP and BP can't be used due to the unknown alignment padding).
2543
2543
if (AFI->isStackRealigned ())
@@ -2548,11 +2548,11 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2548
2548
if (MFI.hasVarSizedObjects ()) {
2549
2549
if (DeallocateBefore && !AFI->hasStackHazardSlotIndex ()) {
2550
2550
// If there's SVE locals and no hazard padding we can do:
2551
- // ADDVL SP, X29 , #(-SVECalleeSavedSize)
2551
+ // ADDVL SP, FP , #(-SVECalleeSavedSize)
2552
2552
return AArch64::FP;
2553
2553
}
2554
2554
// If there's SVE locals and hazard padding we can choose between:
2555
- // SUB TMP, X29 , #(-CalleeSaveBaseOffset)
2555
+ // SUB TMP, FP , #(-CalleeSaveBaseOffset)
2556
2556
// ADDVL SP, TMP, #(-SVECalleeSavedSize)
2557
2557
// OR:
2558
2558
// ADD SP, BP, #NumBytes
@@ -2565,8 +2565,13 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2565
2565
// In the standard case we use the SP.
2566
2566
return AArch64::SP;
2567
2567
}();
2568
-
2569
- if (SVECalleeSavedSize && BaseForSVERestore == AArch64::FP) {
2568
+ // If we have any SVE callee saves they must be restored now.
2569
+ bool MustRestoreSVECalleSaves = SVECalleeSavedSize != 0 ;
2570
+ // If the base for deallocation is the SP we must deallocate the SVE locals
2571
+ // regardless of if we have SVE callee saves. For any other base the SVE
2572
+ // locals will be implicitly deallocated when we set the SP to the FP.
2573
+ bool MustDeallocateSVEArea = BaseForSVEDealloc == AArch64::SP;
2574
+ if (MustRestoreSVECalleSaves && BaseForSVEDealloc == AArch64::FP) {
2570
2575
Register CalleeSaveBase = AArch64::FP;
2571
2576
if (int64_t CalleeSaveBaseOffset =
2572
2577
AFI->getCalleeSaveBaseToFrameRecordOffset ()) {
@@ -2588,16 +2593,15 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2588
2593
emitFrameOffset (MBB, RestoreBegin, DL, AArch64::SP, CalleeSaveBase,
2589
2594
StackOffset::getScalable (-SVECalleeSavedSize), TII,
2590
2595
MachineInstr::FrameDestroy);
2591
- } else if (BaseForSVERestore == AArch64::SP || SVECalleeSavedSize ) {
2596
+ } else if (MustRestoreSVECalleSaves || MustDeallocateSVEArea ) {
2592
2597
if (SVECalleeSavedSize) {
2593
2598
// Deallocate the non-SVE locals first before we can deallocate (and
2594
2599
// restore callee saves) from the SVE area.
2595
2600
emitFrameOffset (
2596
- MBB, RestoreBegin, DL, AArch64::SP, BaseForSVERestore ,
2601
+ MBB, RestoreBegin, DL, AArch64::SP, BaseForSVEDealloc ,
2597
2602
StackOffset::getFixed (NumBytes), TII, MachineInstr::FrameDestroy,
2598
2603
false , NeedsWinCFI, &HasWinCFI, EmitCFI && !hasFP (MF),
2599
2604
SVEStackSize + StackOffset::getFixed (NumBytes + PrologueSaveSize));
2600
-
2601
2605
NumBytes = 0 ;
2602
2606
}
2603
2607
@@ -2607,10 +2611,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2607
2611
SVEStackSize +
2608
2612
StackOffset::getFixed (NumBytes + PrologueSaveSize));
2609
2613
2610
- if (BaseForSVERestore == AArch64::SP) {
2611
- // Note: If the base is not SP it is the base pointer, in which case the
2612
- // SVE CSs will be implicitly deallocated by setting the SP to the FP to
2613
- // restore the non-SVE CSs.
2614
+ if (MustDeallocateSVEArea) {
2614
2615
emitFrameOffset (MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
2615
2616
DeallocateAfter, TII, MachineInstr::FrameDestroy, false ,
2616
2617
NeedsWinCFI, &HasWinCFI, EmitCFI && !hasFP (MF),
0 commit comments