@@ -2537,7 +2537,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
25372537 } else if (SVEStackSize) {
25382538 const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo ();
25392539 int64_t SVECalleeSavedSize = AFI->getSVECalleeSavedStackSize ();
2540- Register BaseForSVERestore = [&]() -> Register {
2540+ Register BaseForSVEDealloc = [&]() -> Register {
25412541 // With stack realignment we must use the FP to restore SVE CSRs (as both
25422542 // the SP and BP can't be used due to the unknown alignment padding).
25432543 if (AFI->isStackRealigned ())
@@ -2548,11 +2548,11 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
25482548 if (MFI.hasVarSizedObjects ()) {
25492549 if (DeallocateBefore && !AFI->hasStackHazardSlotIndex ()) {
25502550 // If there's SVE locals and no hazard padding we can do:
2551- // ADDVL SP, X29 , #(-SVECalleeSavedSize)
2551+ // ADDVL SP, FP , #(-SVECalleeSavedSize)
25522552 return AArch64::FP;
25532553 }
25542554 // If there's SVE locals and hazard padding we can choose between:
2555- // SUB TMP, X29 , #(-CalleeSaveBaseOffset)
2555+ // SUB TMP, FP , #(-CalleeSaveBaseOffset)
25562556 // ADDVL SP, TMP, #(-SVECalleeSavedSize)
25572557 // OR:
25582558 // ADD SP, BP, #NumBytes
@@ -2565,8 +2565,13 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
25652565 // In the standard case we use the SP.
25662566 return AArch64::SP;
25672567 }();
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 area
2571+ // regardless of if we have SVE callee saves. For any other base the SVE
2572+ // area will be implicitly deallocated when we set the SP to the FP.
2573+ bool MustDeallocateSVEArea = BaseForSVEDealloc == AArch64::SP;
2574+ if (MustRestoreSVECalleSaves && BaseForSVEDealloc == AArch64::FP) {
25702575 Register CalleeSaveBase = AArch64::FP;
25712576 if (int64_t CalleeSaveBaseOffset =
25722577 AFI->getCalleeSaveBaseToFrameRecordOffset ()) {
@@ -2588,16 +2593,15 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
25882593 emitFrameOffset (MBB, RestoreBegin, DL, AArch64::SP, CalleeSaveBase,
25892594 StackOffset::getScalable (-SVECalleeSavedSize), TII,
25902595 MachineInstr::FrameDestroy);
2591- } else if (BaseForSVERestore == AArch64::SP || SVECalleeSavedSize ) {
2596+ } else if (MustRestoreSVECalleSaves || MustDeallocateSVEArea ) {
25922597 if (SVECalleeSavedSize) {
25932598 // Deallocate the non-SVE locals first before we can deallocate (and
25942599 // restore callee saves) from the SVE area.
25952600 emitFrameOffset (
2596- MBB, RestoreBegin, DL, AArch64::SP, BaseForSVERestore ,
2601+ MBB, RestoreBegin, DL, AArch64::SP, BaseForSVEDealloc ,
25972602 StackOffset::getFixed (NumBytes), TII, MachineInstr::FrameDestroy,
25982603 false , NeedsWinCFI, &HasWinCFI, EmitCFI && !hasFP (MF),
25992604 SVEStackSize + StackOffset::getFixed (NumBytes + PrologueSaveSize));
2600-
26012605 NumBytes = 0 ;
26022606 }
26032607
@@ -2607,10 +2611,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
26072611 SVEStackSize +
26082612 StackOffset::getFixed (NumBytes + PrologueSaveSize));
26092613
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) {
26142615 emitFrameOffset (MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
26152616 DeallocateAfter, TII, MachineInstr::FrameDestroy, false ,
26162617 NeedsWinCFI, &HasWinCFI, EmitCFI && !hasFP (MF),
0 commit comments