[llvm] [RISCV] Account for ADDI immediate range in select of two constants w/ zicond (PR #155471)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 26 12:18:29 PDT 2025
https://github.com/preames updated https://github.com/llvm/llvm-project/pull/155471
>From 93bfcbb9a744f3b421eca795ccc00324269f79fa Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Tue, 26 Aug 2025 11:50:57 -0700
Subject: [PATCH 1/2] [RISCV] Account for ADDI immediate range in select of two
constants with zicond
When choosing to materialize a select of two constants using zicond,
we have a choice of which direction to compute the delta. The prior
cost was looking only at the cost of the values without accounting
for the fact it's actually the delta which is the highest cost and
that sometimes the addend can fold into an addi.
Note that the addi is also preferrable since it might be folded into
a dependent memory instruction if e.g. we're doing a load from a
select of two constant addresses.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 20 +++++++++++++++-----
llvm/test/CodeGen/RISCV/select-const.ll | 14 ++++++--------
2 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index b84bd1ce0ac50..beee74f4d9215 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -9280,11 +9280,21 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
}
}
- const int TrueValCost = RISCVMatInt::getIntMatCost(
- TrueVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
- const int FalseValCost = RISCVMatInt::getIntMatCost(
- FalseVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
- bool IsCZERO_NEZ = TrueValCost <= FalseValCost;
+ auto getCost = [&](APInt Delta, APInt Addend) {
+ const int DeltaCost = RISCVMatInt::getIntMatCost(
+ Delta, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
+ // Dos the addend folds into an ADDI
+ if (Addend.isSignedIntN(12))
+ return DeltaCost;
+ const int AddendCost = RISCVMatInt::getIntMatCost(
+ Addend, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
+ // Panalize the ADD slightly so that we prefer to end with an ADDI
+ // if costs are otherwise equal. This helps to expose the immediate
+ // for possible folding into a dependent memory instruction.
+ return AddendCost + DeltaCost + 1;
+ };
+ bool IsCZERO_NEZ = getCost(FalseVal - TrueVal, TrueVal) <=
+ getCost(TrueVal - FalseVal, FalseVal);
SDValue LHSVal = DAG.getConstant(
IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal, DL, VT);
SDValue RHSVal =
diff --git a/llvm/test/CodeGen/RISCV/select-const.ll b/llvm/test/CodeGen/RISCV/select-const.ll
index c11b5d9b4a71d..e8019e99a6da9 100644
--- a/llvm/test/CodeGen/RISCV/select-const.ll
+++ b/llvm/test/CodeGen/RISCV/select-const.ll
@@ -506,11 +506,10 @@ define i32 @select_nonnegative_lui_addi(i32 signext %x) {
; RV32ZICOND-LABEL: select_nonnegative_lui_addi:
; RV32ZICOND: # %bb.0:
; RV32ZICOND-NEXT: srli a0, a0, 31
-; RV32ZICOND-NEXT: lui a1, 1048572
-; RV32ZICOND-NEXT: addi a1, a1, 25
-; RV32ZICOND-NEXT: czero.eqz a0, a1, a0
; RV32ZICOND-NEXT: lui a1, 4
-; RV32ZICOND-NEXT: add a0, a0, a1
+; RV32ZICOND-NEXT: addi a1, a1, -25
+; RV32ZICOND-NEXT: czero.nez a0, a1, a0
+; RV32ZICOND-NEXT: addi a0, a0, 25
; RV32ZICOND-NEXT: ret
;
; RV64I-LABEL: select_nonnegative_lui_addi:
@@ -536,11 +535,10 @@ define i32 @select_nonnegative_lui_addi(i32 signext %x) {
; RV64ZICOND-LABEL: select_nonnegative_lui_addi:
; RV64ZICOND: # %bb.0:
; RV64ZICOND-NEXT: srli a0, a0, 63
-; RV64ZICOND-NEXT: lui a1, 1048572
-; RV64ZICOND-NEXT: addi a1, a1, 25
-; RV64ZICOND-NEXT: czero.eqz a0, a1, a0
; RV64ZICOND-NEXT: lui a1, 4
-; RV64ZICOND-NEXT: add a0, a0, a1
+; RV64ZICOND-NEXT: addi a1, a1, -25
+; RV64ZICOND-NEXT: czero.nez a0, a1, a0
+; RV64ZICOND-NEXT: addi a0, a0, 25
; RV64ZICOND-NEXT: ret
%cmp = icmp sgt i32 %x, -1
%cond = select i1 %cmp, i32 16384, i32 25
>From 6bc72be4733f4e05988b2fadbcce35d7ac31b917 Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Tue, 26 Aug 2025 12:14:58 -0700
Subject: [PATCH 2/2] Move the fudge factor to a future pr
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index beee74f4d9215..aa8e5e7d1c949 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -9288,10 +9288,7 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
return DeltaCost;
const int AddendCost = RISCVMatInt::getIntMatCost(
Addend, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
- // Panalize the ADD slightly so that we prefer to end with an ADDI
- // if costs are otherwise equal. This helps to expose the immediate
- // for possible folding into a dependent memory instruction.
- return AddendCost + DeltaCost + 1;
+ return AddendCost + DeltaCost;
};
bool IsCZERO_NEZ = getCost(FalseVal - TrueVal, TrueVal) <=
getCost(TrueVal - FalseVal, FalseVal);
More information about the llvm-commits
mailing list