[llvm] [llvm][RISCV] Tune lowerSelect on zicond for code size (PR #210026)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 03:43:04 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Brandon Wu (4vtomat)
<details>
<summary>Changes</summary>
Selecting 2 non-constant value will be lowered using 2 czero + 1 or if zicond is enabled, when optimizing for code size, it's at least 10 bytes depending on whether or can be compressed or not.
However if we care about code size > performance we can just keep branch instruction to reduce the code sequence to only 1 mv + 1 branch which is at most 8 bytes.
---
Full diff: https://github.com/llvm/llvm-project/pull/210026.diff
2 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+2-1)
- (modified) llvm/test/CodeGen/RISCV/zicond-opts.ll (+42)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 2df58fc2ca9f0..c8eadec987edc 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -10484,7 +10484,8 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
// (select c, t, f) -> (or (czero_eqz t, c), (czero_nez f, c))
// Unless we have the short forward branch optimization.
- if (!Subtarget.hasConditionalMoveFusion())
+ if (!Subtarget.hasConditionalMoveFusion() &&
+ !DAG.getMachineFunction().getFunction().hasMinSize())
return DAG.getNode(
ISD::OR, DL, VT,
DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV),
diff --git a/llvm/test/CodeGen/RISCV/zicond-opts.ll b/llvm/test/CodeGen/RISCV/zicond-opts.ll
index 0568b0e1fae05..2909803f8adb3 100644
--- a/llvm/test/CodeGen/RISCV/zicond-opts.ll
+++ b/llvm/test/CodeGen/RISCV/zicond-opts.ll
@@ -401,3 +401,45 @@ entry:
%clzg = select i1 %iszero, i32 -9, i32 %cast
ret i32 %clzg
}
+
+define i64 @select_wo_minsize(i64 %true, i64 %false, i1 zeroext %c) {
+; RV32ZICOND-LABEL: select_wo_minsize:
+; RV32ZICOND: # %bb.0:
+; RV32ZICOND-NEXT: czero.nez a2, a2, a4
+; RV32ZICOND-NEXT: czero.eqz a0, a0, a4
+; RV32ZICOND-NEXT: czero.nez a3, a3, a4
+; RV32ZICOND-NEXT: czero.eqz a1, a1, a4
+; RV32ZICOND-NEXT: or a0, a0, a2
+; RV32ZICOND-NEXT: or a1, a1, a3
+; RV32ZICOND-NEXT: ret
+;
+; RV64ZICOND-LABEL: select_wo_minsize:
+; RV64ZICOND: # %bb.0:
+; RV64ZICOND-NEXT: czero.nez a1, a1, a2
+; RV64ZICOND-NEXT: czero.eqz a0, a0, a2
+; RV64ZICOND-NEXT: or a0, a0, a1
+; RV64ZICOND-NEXT: ret
+ %r = select i1 %c, i64 %true, i64 %false
+ ret i64 %r
+}
+
+define i64 @select_w_minsize(i64 %true, i64 %false, i1 zeroext %c) minsize {
+; RV32ZICOND-LABEL: select_w_minsize:
+; RV32ZICOND: # %bb.0:
+; RV32ZICOND-NEXT: bnez a4, .LBB16_2
+; RV32ZICOND-NEXT: # %bb.1:
+; RV32ZICOND-NEXT: mv a0, a2
+; RV32ZICOND-NEXT: mv a1, a3
+; RV32ZICOND-NEXT: .LBB16_2:
+; RV32ZICOND-NEXT: ret
+;
+; RV64ZICOND-LABEL: select_w_minsize:
+; RV64ZICOND: # %bb.0:
+; RV64ZICOND-NEXT: bnez a2, .LBB16_2
+; RV64ZICOND-NEXT: # %bb.1:
+; RV64ZICOND-NEXT: mv a0, a1
+; RV64ZICOND-NEXT: .LBB16_2:
+; RV64ZICOND-NEXT: ret
+ %r = select i1 %c, i64 %true, i64 %false
+ ret i64 %r
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/210026
More information about the llvm-commits
mailing list