Skip to content

Commit b51b26e

Browse files
committed
[RISCV] fix SP recovery in the function epilogue
This patch fixes SP register recovery in the function epilogue.
1 parent d0f6777 commit b51b26e

File tree

2 files changed

+72
-37
lines changed

2 files changed

+72
-37
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,19 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
755755
}
756756
}
757757

758+
void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
759+
MachineBasicBlock &MBB,
760+
MachineBasicBlock::iterator MBBI,
761+
const DebugLoc &DL, uint64_t StackSize,
762+
int64_t CFAOffset) const {
763+
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
764+
765+
Register SPReg = getSPReg(STI);
766+
767+
RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
768+
MachineInstr::FrameDestroy, getStackAlign());
769+
}
770+
758771
void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
759772
MachineBasicBlock &MBB) const {
760773
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
@@ -786,20 +799,51 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
786799
--MBBI;
787800
}
788801

789-
const auto &CSI = getUnmanagedCSI(MF, MFI.getCalleeSavedInfo());
802+
const auto &CSI = MFI.getCalleeSavedInfo();
790803

791804
// Skip to before the restores of scalar callee-saved registers
792805
// FIXME: assumes exactly one instruction is used to restore each
793806
// callee-saved register.
794-
auto LastFrameDestroy = MBBI;
795-
if (!CSI.empty())
796-
LastFrameDestroy = std::prev(MBBI, CSI.size());
807+
auto LastFrameDestroy = std::prev(MBBI, getUnmanagedCSI(MF, CSI).size());
797808

798-
uint64_t RealStackSize = getStackSizeWithRVVPadding(MF);
799-
uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize();
800-
uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize();
809+
uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
810+
uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
811+
: getStackSizeWithRVVPadding(MF);
812+
uint64_t StackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
813+
: getStackSizeWithRVVPadding(MF) -
814+
RVFI->getReservedSpillsSize();
815+
uint64_t FPOffset = FirstSPAdjustAmount ? FirstSPAdjustAmount
816+
: getStackSizeWithRVVPadding(MF) -
817+
RVFI->getVarArgsSaveSize();
801818
uint64_t RVVStackSize = RVFI->getRVVStackSize();
802819

820+
bool RestoreFP = RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
821+
!hasReservedCallFrame(MF);
822+
823+
if (RVVStackSize) {
824+
// If restoreFP the stack pointer will be restored using the frame pointer
825+
// value.
826+
if (!RestoreFP) {
827+
adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize,
828+
MachineInstr::FrameDestroy);
829+
}
830+
}
831+
832+
if (FirstSPAdjustAmount) {
833+
uint64_t SecondSPAdjustAmount =
834+
getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
835+
assert(SecondSPAdjustAmount > 0 &&
836+
"SecondSPAdjustAmount should be greater than zero");
837+
838+
// If restoreFP the stack pointer will be restored using the frame pointer
839+
// value.
840+
if (!RestoreFP) {
841+
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg,
842+
StackOffset::getFixed(SecondSPAdjustAmount),
843+
MachineInstr::FrameDestroy, getStackAlign());
844+
}
845+
}
846+
803847
// Restore the stack pointer using the value of the frame pointer. Only
804848
// necessary if the stack pointer was modified, meaning the stack size is
805849
// unknown.
@@ -810,50 +854,37 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
810854
// normally it's just checking the variable sized object is present or not
811855
// is enough, but we also don't preserve that at prologue/epilogue when
812856
// have vector objects in stack.
813-
if (RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
814-
!hasReservedCallFrame(MF)) {
857+
if (RestoreFP) {
815858
assert(hasFP(MF) && "frame pointer should not have been eliminated");
816-
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
817-
StackOffset::getFixed(-FPOffset),
818-
MachineInstr::FrameDestroy, getStackAlign());
819-
} else {
820-
if (RVVStackSize)
821-
adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize,
822-
MachineInstr::FrameDestroy);
823-
}
824-
825-
uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
826-
if (FirstSPAdjustAmount) {
827-
uint64_t SecondSPAdjustAmount =
828-
getStackSizeWithRVVPadding(MF) - FirstSPAdjustAmount;
829-
assert(SecondSPAdjustAmount > 0 &&
830-
"SecondSPAdjustAmount should be greater than zero");
831859

832-
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg,
833-
StackOffset::getFixed(SecondSPAdjustAmount),
834-
MachineInstr::FrameDestroy, getStackAlign());
860+
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
861+
StackOffset::getFixed(-FPOffset), MachineInstr::FrameDestroy,
862+
getStackAlign());
835863
}
836864

837-
if (FirstSPAdjustAmount)
838-
StackSize = FirstSPAdjustAmount;
839-
840-
if (RVFI->isPushable(MF) && MBBI != MBB.end() &&
841-
MBBI->getOpcode() == RISCV::CM_POP) {
865+
bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() &&
866+
MBBI->getOpcode() == RISCV::CM_POP;
867+
if (ApplyPop) {
842868
// Use available stack adjustment in pop instruction to deallocate stack
843869
// space. Align the stack size down to a multiple of 16. This is needed for
844870
// RVE.
845871
// FIXME: Can we increase the stack size to a multiple of 16 instead?
846872
uint64_t Spimm = std::min(alignDown(StackSize, 16), (uint64_t)48);
847873
MBBI->getOperand(1).setImm(Spimm);
848874
StackSize -= Spimm;
849-
}
850875

851-
// Deallocate stack
852-
if (StackSize != 0) {
853-
RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
854-
MachineInstr::FrameDestroy, getStackAlign());
876+
if (StackSize != 0)
877+
deallocateStack(MF, MBB, MBBI, DL, StackSize,
878+
/*stack_adj of cm.pop instr*/ RealStackSize - StackSize);
879+
880+
++MBBI;
855881
}
856882

883+
// Deallocate stack if StackSize isn't a zero and if we didn't already do it
884+
// during cm.pop handling.
885+
if (StackSize != 0 && !ApplyPop)
886+
deallocateStack(MF, MBB, MBBI, DL, StackSize, 0);
887+
857888
// Emit epilogue for shadow call stack.
858889
emitSCSEpilogue(MF, MBB, MBBI, DL);
859890
}

llvm/lib/Target/RISCV/RISCVFrameLowering.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ class RISCVFrameLowering : public TargetFrameLowering {
9191
void emitCalleeSavedRVVPrologCFI(MachineBasicBlock &MBB,
9292
MachineBasicBlock::iterator MI,
9393
bool HasFP) const;
94+
void deallocateStack(MachineFunction &MF, MachineBasicBlock &MBB,
95+
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
96+
uint64_t StackSize, int64_t CFAOffset) const;
97+
9498
std::pair<int64_t, Align>
9599
assignRVVStackObjectOffsets(MachineFunction &MF) const;
96100
};

0 commit comments

Comments
 (0)