[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