diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h @@ -43,6 +43,8 @@ Register getFrameRegister(const MachineFunction &MF) const override; + bool canRealignStack(const MachineFunction &) const override; + bool requiresRegisterScavenging(const MachineFunction &MF) const override { return true; } diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -152,6 +152,23 @@ return TFI->hasFP(MF) ? RISCV::X8 : RISCV::X2; } +bool RISCVRegisterInfo::canRealignStack(const MachineFunction &MF) const { + if (!TargetRegisterInfo::canRealignStack(MF)) + return false; + + // We need the frame pointer (fp) to restore the stack pointer (sp) when + // realigning the stack in the epilog. + Register FPReg = RISCV::X8; + + // In order to use fp, it must not be reserved by the user. + if (MF.getSubtarget().isRegisterReservedByUser(FPReg)) + return false; + + // In order to use fp, we must be able to reserve it. + const MachineRegisterInfo *MRI = &MF.getRegInfo(); + return MRI->canReserveReg(FPReg); +} + const uint32_t * RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & MF, CallingConv::ID /*CC*/) const {