[llvm] [RISCV] Lower (select c, x, -x) -> (sub (czero_eqz x, c), (czero_nez x, c)) with Zicond. (PR #217181)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 17:57:46 PDT 2026
- Previous message: [llvm] [RISCV] Lower (select c, x, -x) -> (sub (czero_eqz x, c), (czero_nez x, c)) with Zicond. (PR #217181)
- Next message: [llvm] [RISCV] Lower (select c, x, -x) -> (sub (czero_eqz x, c), (czero_nez x, c)) with Zicond. (PR #217181)
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Craig Topper (topperc)
<details>
<summary>Changes</summary>
Assisted-by: Claude
---
Full diff: https://github.com/llvm/llvm-project/pull/217181.diff
2 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+22-2)
- (modified) llvm/test/CodeGen/RISCV/condops.ll (+141)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 2dbc048d8dc6b..b10f5a40ef4bd 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -10622,15 +10622,35 @@ 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, or we are
// optimizing for size.
- if (!Subtarget.hasConditionalMoveFusion() && !DAG.shouldOptForSize())
+ if (!Subtarget.hasConditionalMoveFusion() && !DAG.shouldOptForSize()) {
+ using namespace llvm::SDPatternMatch;
+
+ // (select c, x, -x) -> (sub (czero_eqz x, c), (czero_nez x, c))
+ if (sd_match(FalseV, m_Neg(m_Specific(TrueV)))) {
+ TrueV = DAG.getFreeze(TrueV);
+ return DAG.getNode(
+ ISD::SUB, DL, VT,
+ DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV),
+ DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, TrueV, CondV));
+ }
+ // (select c, -x, x) -> (sub (czero_nez x, c), (czero_eqz x, c))
+ if (sd_match(TrueV, m_Neg(m_Specific(FalseV)))) {
+ FalseV = DAG.getFreeze(FalseV);
+ return DAG.getNode(
+ ISD::SUB, DL, VT,
+ DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, CondV),
+ DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, FalseV, CondV));
+ }
+
+ // (select c, t, f) -> (or (czero_eqz t, c), (czero_nez f, c))
return DAG.getNode(
ISD::OR, DL, VT,
DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV),
DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, CondV),
SDNodeFlags::Disjoint);
+ }
}
if (Op.hasOneUse()) {
diff --git a/llvm/test/CodeGen/RISCV/condops.ll b/llvm/test/CodeGen/RISCV/condops.ll
index 71af806811a4b..3c62b322efece 100644
--- a/llvm/test/CodeGen/RISCV/condops.ll
+++ b/llvm/test/CodeGen/RISCV/condops.ll
@@ -4554,3 +4554,144 @@ entry:
%cond = select i1 %tobool.not, i64 0, i64 %x
ret i64 %cond
}
+
+define i64 @neg1(i64 %rs1, i1 zeroext %rc) {
+; RV32I-LABEL: neg1:
+; RV32I: # %bb.0:
+; RV32I-NEXT: bnez a2, .LBB66_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: snez a2, a0
+; RV32I-NEXT: neg a1, a1
+; RV32I-NEXT: sub a1, a1, a2
+; RV32I-NEXT: neg a0, a0
+; RV32I-NEXT: .LBB66_2:
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: neg1:
+; RV64I: # %bb.0:
+; RV64I-NEXT: bnez a1, .LBB66_2
+; RV64I-NEXT: # %bb.1:
+; RV64I-NEXT: neg a0, a0
+; RV64I-NEXT: .LBB66_2:
+; RV64I-NEXT: ret
+;
+; RV32XVENTANACONDOPS-LABEL: neg1:
+; RV32XVENTANACONDOPS: # %bb.0:
+; RV32XVENTANACONDOPS-NEXT: neg a3, a1
+; RV32XVENTANACONDOPS-NEXT: snez a4, a0
+; RV32XVENTANACONDOPS-NEXT: sub a3, a3, a4
+; RV32XVENTANACONDOPS-NEXT: vt.maskcn a4, a0, a2
+; RV32XVENTANACONDOPS-NEXT: vt.maskc a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT: vt.maskc a1, a1, a2
+; RV32XVENTANACONDOPS-NEXT: vt.maskcn a2, a3, a2
+; RV32XVENTANACONDOPS-NEXT: sub a0, a0, a4
+; RV32XVENTANACONDOPS-NEXT: or a1, a1, a2
+; RV32XVENTANACONDOPS-NEXT: ret
+;
+; RV64XVENTANACONDOPS-LABEL: neg1:
+; RV64XVENTANACONDOPS: # %bb.0:
+; RV64XVENTANACONDOPS-NEXT: vt.maskcn a2, a0, a1
+; RV64XVENTANACONDOPS-NEXT: vt.maskc a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT: sub a0, a0, a2
+; RV64XVENTANACONDOPS-NEXT: ret
+;
+; RV64XTHEADCONDMOV-LABEL: neg1:
+; RV64XTHEADCONDMOV: # %bb.0:
+; RV64XTHEADCONDMOV-NEXT: neg a2, a0
+; RV64XTHEADCONDMOV-NEXT: th.mveqz a0, a2, a1
+; RV64XTHEADCONDMOV-NEXT: ret
+;
+; RV32ZICOND-LABEL: neg1:
+; RV32ZICOND: # %bb.0:
+; RV32ZICOND-NEXT: neg a3, a1
+; RV32ZICOND-NEXT: snez a4, a0
+; RV32ZICOND-NEXT: sub a3, a3, a4
+; RV32ZICOND-NEXT: czero.nez a4, a0, a2
+; RV32ZICOND-NEXT: czero.eqz a0, a0, a2
+; RV32ZICOND-NEXT: czero.eqz a1, a1, a2
+; RV32ZICOND-NEXT: czero.nez a2, a3, a2
+; RV32ZICOND-NEXT: sub a0, a0, a4
+; RV32ZICOND-NEXT: or a1, a1, a2
+; RV32ZICOND-NEXT: ret
+;
+; RV64ZICOND-LABEL: neg1:
+; RV64ZICOND: # %bb.0:
+; RV64ZICOND-NEXT: czero.nez a2, a0, a1
+; RV64ZICOND-NEXT: czero.eqz a0, a0, a1
+; RV64ZICOND-NEXT: sub a0, a0, a2
+; RV64ZICOND-NEXT: ret
+ %neg = sub i64 0, %rs1
+ %sel = select i1 %rc, i64 %rs1, i64 %neg
+ ret i64 %sel
+}
+
+define i64 @neg2(i64 %rs1, i1 zeroext %rc) {
+; RV32I-LABEL: neg2:
+; RV32I: # %bb.0:
+; RV32I-NEXT: beqz a2, .LBB67_2
+; RV32I-NEXT: # %bb.1:
+; RV32I-NEXT: snez a2, a0
+; RV32I-NEXT: neg a1, a1
+; RV32I-NEXT: sub a1, a1, a2
+; RV32I-NEXT: neg a0, a0
+; RV32I-NEXT: .LBB67_2:
+; RV32I-NEXT: ret
+;
+; RV64I-LABEL: neg2:
+; RV64I: # %bb.0:
+; RV64I-NEXT: beqz a1, .LBB67_2
+; RV64I-NEXT: # %bb.1:
+; RV64I-NEXT: neg a0, a0
+; RV64I-NEXT: .LBB67_2:
+; RV64I-NEXT: ret
+;
+; RV32XVENTANACONDOPS-LABEL: neg2:
+; RV32XVENTANACONDOPS: # %bb.0:
+; RV32XVENTANACONDOPS-NEXT: neg a3, a1
+; RV32XVENTANACONDOPS-NEXT: snez a4, a0
+; RV32XVENTANACONDOPS-NEXT: sub a3, a3, a4
+; RV32XVENTANACONDOPS-NEXT: vt.maskc a4, a0, a2
+; RV32XVENTANACONDOPS-NEXT: vt.maskcn a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT: vt.maskcn a1, a1, a2
+; RV32XVENTANACONDOPS-NEXT: vt.maskc a2, a3, a2
+; RV32XVENTANACONDOPS-NEXT: sub a0, a0, a4
+; RV32XVENTANACONDOPS-NEXT: or a1, a2, a1
+; RV32XVENTANACONDOPS-NEXT: ret
+;
+; RV64XVENTANACONDOPS-LABEL: neg2:
+; RV64XVENTANACONDOPS: # %bb.0:
+; RV64XVENTANACONDOPS-NEXT: vt.maskc a2, a0, a1
+; RV64XVENTANACONDOPS-NEXT: vt.maskcn a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT: sub a0, a0, a2
+; RV64XVENTANACONDOPS-NEXT: ret
+;
+; RV64XTHEADCONDMOV-LABEL: neg2:
+; RV64XTHEADCONDMOV: # %bb.0:
+; RV64XTHEADCONDMOV-NEXT: neg a2, a0
+; RV64XTHEADCONDMOV-NEXT: th.mvnez a0, a2, a1
+; RV64XTHEADCONDMOV-NEXT: ret
+;
+; RV32ZICOND-LABEL: neg2:
+; RV32ZICOND: # %bb.0:
+; RV32ZICOND-NEXT: neg a3, a1
+; RV32ZICOND-NEXT: snez a4, a0
+; RV32ZICOND-NEXT: sub a3, a3, a4
+; RV32ZICOND-NEXT: czero.eqz a4, a0, a2
+; RV32ZICOND-NEXT: czero.nez a0, a0, a2
+; RV32ZICOND-NEXT: czero.nez a1, a1, a2
+; RV32ZICOND-NEXT: czero.eqz a2, a3, a2
+; RV32ZICOND-NEXT: sub a0, a0, a4
+; RV32ZICOND-NEXT: or a1, a2, a1
+; RV32ZICOND-NEXT: ret
+;
+; RV64ZICOND-LABEL: neg2:
+; RV64ZICOND: # %bb.0:
+; RV64ZICOND-NEXT: czero.eqz a2, a0, a1
+; RV64ZICOND-NEXT: czero.nez a0, a0, a1
+; RV64ZICOND-NEXT: sub a0, a0, a2
+; RV64ZICOND-NEXT: ret
+ %neg = sub i64 0, %rs1
+ %sel = select i1 %rc, i64 %neg, i64 %rs1
+ ret i64 %sel
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/217181
- Previous message: [llvm] [RISCV] Lower (select c, x, -x) -> (sub (czero_eqz x, c), (czero_nez x, c)) with Zicond. (PR #217181)
- Next message: [llvm] [RISCV] Lower (select c, x, -x) -> (sub (czero_eqz x, c), (czero_nez x, c)) with Zicond. (PR #217181)
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the llvm-commits
mailing list