[llvm] [RISCV] Stash GPR to FPR if emergency spill slot is not reachable (PR #180685)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 10 01:46:33 PST 2026


LukeZhuang wrote:

> This seems like a hack. It doesn't work when the D extension isn't present.
> 
> I think the patch below is the beginning of a better fix, but it causes other issues that need to be worked through. Ignore the mention of ARM. This was copy and pasted as an experiment to fix #180199.
> 
> ```
> @@ -1860,7 +1864,16 @@ void RISCVFrameLowering::processFunctionBeforeFrameFinalized(
>  // by the frame pointer.
>  // Let eliminateCallFramePseudoInstr preserve stack space for it.
>  bool RISCVFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
> -  return !MF.getFrameInfo().hasVarSizedObjects() &&
> +  const MachineFrameInfo &MFI = MF.getFrameInfo();
> +  unsigned CFSize = MFI.getMaxCallFrameSize();
> +  // It's not always a good idea to include the call frame as part of the
> +  // stack frame. ARM (especially Thumb) has small immediate offset to
> +  // address the stack frame. So a large call frame can cause poor codegen
> +  // and may even makes it impossible to scavenge a register.
> +  if (CFSize >= ((1 << 12) - 1) / 2)  // Half of imm12
> +    return false;
> +
> +  return !MFI.hasVarSizedObjects() &&
>           !(hasFP(MF) && hasRVVFrameObject(MF));
>  }
> ```

And sorry I do not fully understand your solution. May I ask what is the expected generated code be like using frame pointer?
I thought the issue comes from the backend structure. The things RegisterScavenger can do is quite limited, since the main structure is already mostly fixed after RA. Unless we "reserve" some registers in RA for future uses, I'm not sure if it can have such overhead.

https://github.com/llvm/llvm-project/pull/180685


More information about the llvm-commits mailing list