[llvm] [RISCV] Check SP-relative offset in needsFrameBaseReg when FP offset overflows (PR #197368)
Garvit Gupta via llvm-commits
llvm-commits at lists.llvm.org
Tue May 12 23:09:54 PDT 2026
https://github.com/quic-garvgupt created https://github.com/llvm/llvm-project/pull/197368
When a frame pointer is present, `needsFrameBaseReg` previously only checked the FP-relative offset to decide if a virtual base register was needed. If the worst-case FP offset exceeded the 12-bit immediate range, a base register was always materialized, even when the SP-relative offset would fit.
Since `getFrameIndexReference` can now select SP over FP when the offset fits in the compressed instruction immediate range, also check the SP-relative offset before deciding a base register is needed. This avoids unnecessary base register materialization and results in some code size savings.
>From 852e3e25e7c9d825405b16f07cd69e23c08b53b8 Mon Sep 17 00:00:00 2001
From: Garvit Gupta <garvgupt at qti.qualcomm.com>
Date: Tue, 12 May 2026 23:06:44 -0700
Subject: [PATCH] [RISCV] Check SP-relative offset in needsFrameBaseReg when FP
offset overflows
When a frame pointer is present, needsFrameBaseReg previously only
checked the FP-relative offset to decide if a virtual base register
was needed. If the worst-case FP offset exceeded the 12-bit
immediate range, a base register was always materialized, even when the
SP-relative offset would fit.
Since getFrameIndexReference can now select SP over FP when the offset
fits in the compressed instruction immediate range, also check the
SP-relative offset before deciding a base register is needed. This
avoids unnecessary base register materialization and results in some
code size savings.
---
llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp | 8 +++++++-
llvm/test/CodeGen/RISCV/local-stack-slot-allocation.ll | 5 ++---
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index 6baa30cf9e6f6..30441eaee87f0 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -725,7 +725,13 @@ bool RISCVRegisterInfo::needsFrameBaseReg(MachineInstr *MI,
}
int64_t MaxFPOffset = Offset - CalleeSavedSize;
- return !isFrameOffsetLegal(MI, RISCV::X8, MaxFPOffset);
+ if (isFrameOffsetLegal(MI, RISCV::X8, MaxFPOffset))
+ return false;
+
+ // If the FP-relative offset doesn't fit, fall through to check the
+ // SP-relative offset. getFrameIndexReference may select SP over FP when
+ // the SP offset fits in the compressed instruction immediate range, so a
+ // base register might not be needed.
}
// Assume 128 bytes spill slots size to estimate the maximum possible
diff --git a/llvm/test/CodeGen/RISCV/local-stack-slot-allocation.ll b/llvm/test/CodeGen/RISCV/local-stack-slot-allocation.ll
index 1ad78f4112351..9a535943d837d 100644
--- a/llvm/test/CodeGen/RISCV/local-stack-slot-allocation.ll
+++ b/llvm/test/CodeGen/RISCV/local-stack-slot-allocation.ll
@@ -153,9 +153,8 @@ define void @frame_pointer() "frame-pointer"="all" {
; RV64I-NEXT: addi s0, sp, 2032
; RV64I-NEXT: .cfi_def_cfa s0, 0
; RV64I-NEXT: addi sp, sp, -496
-; RV64I-NEXT: addi a0, sp, 556
-; RV64I-NEXT: lbu a1, 0(a0)
-; RV64I-NEXT: sb a1, 0(a0)
+; RV64I-NEXT: lbu a0, 556(sp)
+; RV64I-NEXT: sb a0, 556(sp)
; RV64I-NEXT: addi sp, sp, 496
; RV64I-NEXT: .cfi_def_cfa sp, 2032
; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload
More information about the llvm-commits
mailing list