RISC-V: Avoid frame-pointer references in epilogue stack ties
Prevents incorrect frame pointer usage in RISC-V epilogues, avoiding register corruption during unwinding.
This commit addresses an issue in the RISC-V backend where epilogue stack ties incorrectly referenced the frame pointer (s0) when no frame pointer was used. This made the register appear live, potentially leading to regrename corrupting callee-saved state during exception unwinding. The fix introduces a new SP-only pattern for epilogue barriers, ensuring stack ties correctly reference only the stack pointer when a frame pointer is absent, thus preserving unwinding integrity.
In Details
On RISC-V, stack ties are used in epilogues to mark stack frame changes for unwinders. When a frame pointer (s0) is not used, the original pattern for stack_tie incorrectly referenced s0, causing it to be considered live by later passes like regrename. This could lead to s0 being modified when it should have been preserved as callee-saved. The fix introduces a dedicated stack_tie_sp pattern for epilogue barriers that only uses the stack pointer (sp), ensuring correctness regardless of frame pointer usage and preventing unwind corruption.
- stack tie
- A pseudo-instruction or marker used in compiler intermediate representations to indicate changes in the stack frame, often for debugging or exception handling.
- epilogue
- The part of a function that executes just before returning, typically responsible for restoring the stack frame and cleaning up local state.
- frame pointer
- A register (often
s0on RISC-V) used to keep track of the base of the current function's stack frame, facilitating access to local variables and arguments. - callee-saved registers
- Registers that a called function must preserve its original value across the function call. The caller relies on these registers retaining their values.
- exception unwinding
- The process of walking back up the call stack to find an exception handler when an exception is thrown.
- CFA
- Common Frame Address, a value representing the base of the current stack frame, often used in debugging and unwinding information.