[llvm] [RISCV] Fix prefetch ADDI-adjustment range upper bound (PR #215985)
Kane Wang via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 13 01:22:53 PDT 2026
https://github.com/ReVe1uv created https://github.com/llvm/llvm-project/pull/215985
SelectAddrRegImmLsb00000 folds a large constant offset into an ADDI plus a simm12_lsb00000 prefetch immediate. The positive range [2017, 4065] overflowed simm12 at the top end: CVal - 2016 reaches 2048/2049, producing an invalid ADDI. Narrow it to 4063; 4064/4065 now fall through to selectConstantAddr instead.
>From 517a0fb2270494ae225ac13f36dfb1ff94079188 Mon Sep 17 00:00:00 2001
From: Kane Wang <wangqiang1 at kylinos.cn>
Date: Thu, 13 Aug 2026 16:17:27 +0800
Subject: [PATCH] [RISCV] Fix prefetch ADDI-adjustment range upper bound
SelectAddrRegImmLsb00000 folds a large constant offset into an ADDI
plus a simm12_lsb00000 prefetch immediate. The positive range [2017,
4065] overflowed simm12 at the top end: CVal - 2016 reaches 2048/2049,
producing an invalid ADDI. Narrow it to 4063; 4064/4065 now fall
through to selectConstantAddr instead.
---
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 6 +++--
llvm/test/CodeGen/RISCV/prefetch.ll | 28 +++++++++++++++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index d297b2857e2ab..a5ac493c7dc90 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3716,9 +3716,11 @@ bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
int64_t CVal = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
assert(!isInt<12>(CVal) && "simm12 not already handled?");
- // Handle immediates in the range [-4096,-2049] or [2017, 4065]. We can save
+ // Handle immediates in the range [-4096,-2049] or [2017, 4063]. We can save
// one instruction by folding adjustment (-2048 or 2016) into the address.
- if ((-2049 >= CVal && CVal >= -4096) || (4065 >= CVal && CVal >= 2017)) {
+ // The upper bound keeps CVal - 2016 within simm12 ([−2048, 2047]); 4064/4065
+ // would yield 2048/2049 and overflow the ADDI immediate.
+ if ((-2049 >= CVal && CVal >= -4096) || (4063 >= CVal && CVal >= 2017)) {
int64_t Adj = CVal < 0 ? -2048 : 2016;
int64_t AdjustedOffset = CVal - Adj;
Base =
diff --git a/llvm/test/CodeGen/RISCV/prefetch.ll b/llvm/test/CodeGen/RISCV/prefetch.ll
index eba1c535c254e..5fb808edcc1f5 100644
--- a/llvm/test/CodeGen/RISCV/prefetch.ll
+++ b/llvm/test/CodeGen/RISCV/prefetch.ll
@@ -240,6 +240,34 @@ define void @test_prefetch_offsetable_8(ptr %a) nounwind {
ret void
}
+define void @test_prefetch_offsetable_10(ptr %a) nounwind {
+; CHECK-LABEL: test_prefetch_offsetable_10:
+; CHECK: # %bb.0:
+; CHECK-NEXT: addi a0, a0, 2047
+; CHECK-NEXT: ntl.all
+; CHECK-NEXT: prefetch.r 2016(a0)
+; CHECK-NEXT: ret
+ %addr = getelementptr i8, ptr %a, i64 4063
+ call void @llvm.prefetch(ptr %addr, i32 0, i32 0, i32 1)
+ ret void
+}
+
+; The upper bound of the ADDI-adjustment range. 4064 = 2016 + 2048 would
+; overflow simm12 (max 2047) in the folded ADDI, so it must instead be split
+; into LUI + simm12 by selectConstantAddr.
+define void @test_prefetch_offsetable_11(ptr %a) nounwind {
+; CHECK-LABEL: test_prefetch_offsetable_11:
+; CHECK: # %bb.0:
+; CHECK-NEXT: lui a1, 1
+; CHECK-NEXT: add a0, a0, a1
+; CHECK-NEXT: ntl.all
+; CHECK-NEXT: prefetch.r -32(a0)
+; CHECK-NEXT: ret
+ %addr = getelementptr i8, ptr %a, i64 4064
+ call void @llvm.prefetch(ptr %addr, i32 0, i32 0, i32 1)
+ ret void
+}
+
define void @test_prefetch_frameindex_0() nounwind {
; CHECK-LABEL: test_prefetch_frameindex_0:
; CHECK: # %bb.0:
More information about the llvm-commits
mailing list