diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/IR/DiagnosticInfo.h" @@ -548,6 +549,7 @@ const RISCVRegisterInfo *RI = STI.getRegisterInfo(); MachineFrameInfo &MFI = MF.getFrameInfo(); auto *RVFI = MF.getInfo(); + const RISCVInstrInfo *TII = STI.getInstrInfo(); Register FPReg = getFPReg(STI); Register SPReg = getSPReg(STI); @@ -615,12 +617,55 @@ MachineInstr::FrameDestroy); } + if (hasFP(MF) && StackSize != 0) { + // To find the instruction restoring FP from stack. + for (auto &I = LastFrameDestroy; I != MBBI; ++I) { + if (I->mayLoad() && I->getOperand(0).isReg()) { + Register DestReg = I->getOperand(0).getReg(); + if (DestReg == FPReg) { + // We need adjust CFA back to the correct sp-based offset. + // Emit ".cfi_def_cfa $sp, CFAOffset" + uint64_t CFAOffset = + FirstSPAdjustAmount + ? -FirstSPAdjustAmount + RVFI->getVarArgsSaveSize() + : FPOffset; + unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa( + nullptr, RI->getDwarfRegNum(SPReg, true), CFAOffset)); + BuildMI(MBB, std::next(I), DL, + TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); + break; + } + } + } + } + + // Emit ".cfi_def_cfa $sp, FPOffset" + if (!hasFP(MF) && FPOffset != 0) { + unsigned regSP = RI->getDwarfRegNum(SPReg, true); + unsigned CFIIndex = + MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, regSP, FPOffset)); + BuildMI(MBB, LastFrameDestroy, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); + } + if (FirstSPAdjustAmount) StackSize = FirstSPAdjustAmount; // Deallocate stack adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); + // Update the CFA information to ensure that the stack debugging information + // can finds the calling information of the Caller function + if (StackSize != 0) { + unsigned regSP = RI->getDwarfRegNum(SPReg, true); + // Emit ".cfi_def_cfa $sp, 0". + unsigned CFIIndex = + MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, regSP, 0)); + BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); + } + // Emit epilogue for shadow call stack. emitSCSEpilogue(MF, MBB, MBBI, DL); } diff --git a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll --- a/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll +++ b/llvm/test/DebugInfo/RISCV/relax-debug-frame.ll @@ -8,8 +8,8 @@ ; RELAX-NEXT: 0x20 R_RISCV_ADD32 - 0x0 ; RELAX-NEXT: 0x20 R_RISCV_SUB32 - 0x0 ; RELAX-NOT: } -; RELAX: 0x39 R_RISCV_SET6 - 0x0 -; RELAX-NEXT: 0x39 R_RISCV_SUB6 - 0x0 +; RELAX: 0x25 R_RISCV_SET6 - 0x0 +; RELAX-NEXT: 0x25 R_RISCV_SUB6 - 0x0 ; ; RELAX-DWARFDUMP-NOT: error: failed to compute relocation ; RELAX-DWARFDUMP: CIE