[llvm] [RISCV] Stash GPR to FPR if emergency spill slot is not reachable (PR #180685)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 10 10:17:46 PST 2026
topperc wrote:
> > May I ask what is the expected generated code be like using frame pointer?
>
> Because the crux of this problem is that offset is too far away from sp -- which points at the low address of the current frame -- we can instead access the far stack slots from _the other_ direction using fp (assuming it exists), which points at the high address of the current frame.
To elaborate on this. RISC-V alllocates 1, 2, or 3 emergency spill slots for the register scavenger. These spill slots must be placed somewhere where they can be addressed without needing a temporary register. Without a frame pointer, we try to place the slots near the stack pointer. Unfortunately, we allocate a reserved call frame space(the size of the largest call frame needed) after the emergency spill slot. If the reserved call frame space exceeds 2047 bytes, the emergency spill slots become too far away from SP. When the frame pointer is enabled we save the SP on entry to the function into the `s0` register. The emergency spill slots are placed so it is near where `s0` points so we can use a small offset from `s0` to do the emergency spill.
The ARM approach was to disable the reserved call frame when it is too large. This requires changing `RestoreSPFromFP` in `emitEpilog` and handling a non-zero `SPAdj` in `RISCVRegisterInfo::eliminateFrameIndex`.
My other thought was to force the use of the frame pointer if the reserved call area is too large.
https://github.com/llvm/llvm-project/pull/180685
More information about the llvm-commits
mailing list