@@ -1360,14 +1360,24 @@ void AArch64EpilogueEmitter::emitEpilogue() {
13601360 }
13611361
13621362 bool CombineSPBump = shouldCombineCSRLocalStackBump (NumBytes);
1363- // Assume we can't combine the last pop with the sp restore.
1364- bool CombineAfterCSRBump = false ;
1363+
1364+ unsigned ProloguePopSize = PrologueSaveSize ;
13651365 if (SVELayout == SVEStackLayout::CalleeSavesAboveFrameRecord) {
1366+ // With CalleeSavesAboveFrameRecord ProloguePopSize is the amount of stack
1367+ // that needs to be popped until we reach the start of the SVE save area.
1368+ // The "FixedObject" stack occurs after the SVE area and must be popped
1369+ // later.
1370+ ProloguePopSize -= FixedObject;
13661371 AfterCSRPopSize += FixedObject;
1367- } else if (!CombineSPBump && PrologueSaveSize != 0 ) {
1372+ }
1373+
1374+ // Assume we can't combine the last pop with the sp restore.
1375+ if (!CombineSPBump && ProloguePopSize != 0 ) {
13681376 MachineBasicBlock::iterator Pop = std::prev (MBB.getFirstTerminator ());
13691377 while (Pop->getOpcode () == TargetOpcode::CFI_INSTRUCTION ||
1370- AArch64InstrInfo::isSEHInstruction (*Pop))
1378+ AArch64InstrInfo::isSEHInstruction (*Pop) ||
1379+ (SVELayout == SVEStackLayout::CalleeSavesAboveFrameRecord &&
1380+ isPartOfSVECalleeSaves (Pop)))
13711381 Pop = std::prev (Pop);
13721382 // Converting the last ldp to a post-index ldp is valid only if the last
13731383 // ldp's offset is 0.
@@ -1377,18 +1387,27 @@ void AArch64EpilogueEmitter::emitEpilogue() {
13771387 // may clobber), convert it to a post-index ldp.
13781388 if (OffsetOp.getImm () == 0 && AfterCSRPopSize >= 0 ) {
13791389 convertCalleeSaveRestoreToSPPrePostIncDec (
1380- Pop, DL, PrologueSaveSize, EmitCFI, MachineInstr::FrameDestroy,
1381- PrologueSaveSize);
1390+ Pop, DL, ProloguePopSize, EmitCFI, MachineInstr::FrameDestroy,
1391+ ProloguePopSize);
1392+ } else if (SVELayout == SVEStackLayout::CalleeSavesAboveFrameRecord) {
1393+ MachineBasicBlock::iterator AfterLastPop = std::next (Pop);
1394+ if (AArch64InstrInfo::isSEHInstruction (*AfterLastPop))
1395+ ++AfterLastPop;
1396+ // If not, and CalleeSavesAboveFrameRecord is enabled, deallocate
1397+ // callee-save non-SVE registers to move the stack pointer to the start of
1398+ // the SVE area.
1399+ emitFrameOffset (MBB, AfterLastPop, DL, AArch64::SP, AArch64::SP,
1400+ StackOffset::getFixed (ProloguePopSize), TII,
1401+ MachineInstr::FrameDestroy, false , NeedsWinCFI,
1402+ &HasWinCFI);
13821403 } else {
1383- // If not , make sure to emit an add after the last ldp.
1404+ // Otherwise , make sure to emit an add after the last ldp.
13841405 // We're doing this by transferring the size to be restored from the
13851406 // adjustment *before* the CSR pops to the adjustment *after* the CSR
13861407 // pops.
1387- AfterCSRPopSize += PrologueSaveSize;
1388- CombineAfterCSRBump = true ;
1408+ AfterCSRPopSize += ProloguePopSize;
13891409 }
13901410 }
1391-
13921411 // Move past the restores of the callee-saved registers.
13931412 // If we plan on combining the sp bump of the local stack size and the callee
13941413 // save stack size, we might need to adjust the CSR save and restore offsets.
@@ -1419,6 +1438,17 @@ void AArch64EpilogueEmitter::emitEpilogue() {
14191438 --SEHEpilogueStartI;
14201439 }
14211440
1441+ // Determine the ranges of SVE callee-saves. This is done before emitting any
1442+ // code at the end of the epilogue (for Swift async), which can get in the way
1443+ // of finding SVE callee-saves with CalleeSavesAboveFrameRecord.
1444+ auto [PPR, ZPR] = getSVEStackFrameSizes ();
1445+ auto [PPRRange, ZPRRange] = partitionSVECS (
1446+ MBB,
1447+ SVELayout == SVEStackLayout::CalleeSavesAboveFrameRecord
1448+ ? MBB.getFirstTerminator ()
1449+ : FirstGPRRestoreI,
1450+ PPR.CalleeSavesSize , ZPR.CalleeSavesSize , /* IsEpilogue=*/ true );
1451+
14221452 if (HasFP && AFI->hasSwiftAsyncContext ())
14231453 emitSwiftAsyncContextFramePointer (EpilogueEndI, DL);
14241454
@@ -1441,14 +1471,6 @@ void AArch64EpilogueEmitter::emitEpilogue() {
14411471 NumBytes -= PrologueSaveSize;
14421472 assert (NumBytes >= 0 && " Negative stack allocation size!?" );
14431473
1444- auto [PPR, ZPR] = getSVEStackFrameSizes ();
1445- auto [PPRRange, ZPRRange] = partitionSVECS (
1446- MBB,
1447- SVELayout == SVEStackLayout::CalleeSavesAboveFrameRecord
1448- ? MBB.getFirstTerminator ()
1449- : FirstGPRRestoreI,
1450- PPR.CalleeSavesSize , ZPR.CalleeSavesSize , /* IsEpilogue=*/ true );
1451-
14521474 StackOffset SVECalleeSavesSize = ZPR.CalleeSavesSize + PPR.CalleeSavesSize ;
14531475 StackOffset SVEStackSize =
14541476 SVECalleeSavesSize + PPR.LocalsSize + ZPR.LocalsSize ;
@@ -1467,16 +1489,6 @@ void AArch64EpilogueEmitter::emitEpilogue() {
14671489 NeedsWinCFI, &HasWinCFI);
14681490 }
14691491
1470- // Deallocate callee-save non-SVE registers.
1471- emitFrameOffset (MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
1472- StackOffset::getFixed (AFI->getCalleeSavedStackSize ()), TII,
1473- MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI);
1474-
1475- // Deallocate fixed objects.
1476- emitFrameOffset (MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
1477- StackOffset::getFixed (FixedObject), TII,
1478- MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI);
1479-
14801492 // Deallocate callee-save SVE registers.
14811493 emitFrameOffset (MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
14821494 SVECalleeSavesSize, TII, MachineInstr::FrameDestroy, false ,
@@ -1619,7 +1631,7 @@ void AArch64EpilogueEmitter::emitEpilogue() {
16191631 MBB, MBB.getFirstTerminator (), DL, AArch64::SP, AArch64::SP,
16201632 StackOffset::getFixed (AfterCSRPopSize), TII, MachineInstr::FrameDestroy,
16211633 false , NeedsWinCFI, &HasWinCFI, EmitCFI,
1622- StackOffset::getFixed (CombineAfterCSRBump ? PrologueSaveSize : 0 ));
1634+ StackOffset::getFixed (AfterCSRPopSize - ArgumentStackToRestore ));
16231635 }
16241636}
16251637
0 commit comments