[llvm] [RISCV] Fold (sext_inreg (setcc), i1) -> (sub 0, (setcc). (PR #154206)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 18 17:51:39 PDT 2025
https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/154206
>From e4ad11162cdf4fe8bcb1c38fd5cd75f12fcfb62f Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 18 Aug 2025 14:10:24 -0700
Subject: [PATCH 1/4] Pre-commit tests
---
llvm/test/CodeGen/RISCV/rv32xandesperf.ll | 25 ++++++++
llvm/test/CodeGen/RISCV/rv32xtheadbb.ll | 38 ++++++++++++
llvm/test/CodeGen/RISCV/rv64xandesperf.ll | 50 +++++++++++++++
llvm/test/CodeGen/RISCV/rv64xtheadbb.ll | 76 +++++++++++++++++++++++
llvm/test/CodeGen/RISCV/xqcibm-extract.ll | 50 +++++++++++++++
5 files changed, 239 insertions(+)
diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
index 6f1d168358e2e..45d1324495506 100644
--- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -377,6 +377,31 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
ret i8 %sext
}
+; Make sure we don't use seqz+nds.bfos instead of snez+addi
+define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
+; CHECK-LABEL: sexti1_i32_setcc_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xor a0, a0, a1
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %icmp = icmp eq i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
+
+; Make sure we don't use nds.bfos instead of neg.
+define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {
+; CHECK-LABEL: sexti1_i32_setcc_3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: slt a0, a0, a1
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %icmp = icmp slt i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
+
define i32 @sexti8_i32(i32 %a) {
; CHECK-LABEL: sexti8_i32:
; CHECK: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
index 784f08ca616cc..96db7e1e8e38f 100644
--- a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
@@ -334,6 +334,44 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
ret i8 %sext
}
+; Make sure we don't use seqz+th.ext instead of snez+addi
+define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
+; RV32I-LABEL: sexti1_i32_setcc_2:
+; RV32I: # %bb.0:
+; RV32I-NEXT: xor a0, a0, a1
+; RV32I-NEXT: snez a0, a0
+; RV32I-NEXT: addi a0, a0, -1
+; RV32I-NEXT: ret
+;
+; RV32XTHEADBB-LABEL: sexti1_i32_setcc_2:
+; RV32XTHEADBB: # %bb.0:
+; RV32XTHEADBB-NEXT: xor a0, a0, a1
+; RV32XTHEADBB-NEXT: seqz a0, a0
+; RV32XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV32XTHEADBB-NEXT: ret
+ %icmp = icmp eq i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
+
+; Make sure we don't use th.ext instead of neg.
+define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {
+; RV32I-LABEL: sexti1_i32_setcc_3:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slt a0, a0, a1
+; RV32I-NEXT: neg a0, a0
+; RV32I-NEXT: ret
+;
+; RV32XTHEADBB-LABEL: sexti1_i32_setcc_3:
+; RV32XTHEADBB: # %bb.0:
+; RV32XTHEADBB-NEXT: slt a0, a0, a1
+; RV32XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV32XTHEADBB-NEXT: ret
+ %icmp = icmp slt i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
+
define i32 @sextb_i32(i32 %a) nounwind {
; RV32I-LABEL: sextb_i32:
; RV32I: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
index 406e5247ae0dd..00004ba516afb 100644
--- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -290,6 +290,31 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
ret i8 %sext
}
+; Make sure we don't use seqz+nds.bfos instead of snez+addi
+define signext i32 @sexti1_i32_setcc_2(i32 signext %a, i32 signext %b) {
+; CHECK-LABEL: sexti1_i32_setcc_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xor a0, a0, a1
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %icmp = icmp eq i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
+
+; Make sure we don't use nds.bfos instead of neg.
+define signext i32 @sexti1_i32_setcc_3(i32 signext %a, i32 signext %b) {
+; CHECK-LABEL: sexti1_i32_setcc_3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: slt a0, a0, a1
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %icmp = icmp slt i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
+
define signext i32 @sexti8_i32(i32 signext %a) {
; CHECK-LABEL: sexti8_i32:
; CHECK: # %bb.0:
@@ -360,6 +385,31 @@ define zeroext i8 @sexti1_i64_setcc(i64 %a) {
ret i8 %sext
}
+; Make sure we don't use seqz+nds.bfos instead of snez+addi
+define i64 @sexti1_i64_setcc_2(i64 %a, i64 %b) {
+; CHECK-LABEL: sexti1_i64_setcc_2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: xor a0, a0, a1
+; CHECK-NEXT: seqz a0, a0
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %icmp = icmp eq i64 %a, %b
+ %sext = sext i1 %icmp to i64
+ ret i64 %sext
+}
+
+; Make sure we don't use nds.bfos instead of neg.
+define i64 @sexti1_i64_setcc_3(i64 %a, i64 %b) {
+; CHECK-LABEL: sexti1_i64_setcc_3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: slt a0, a0, a1
+; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: ret
+ %icmp = icmp slt i64 %a, %b
+ %sext = sext i1 %icmp to i64
+ ret i64 %sext
+}
+
define i64 @sexti8_i64(i64 %a) {
; CHECK-LABEL: sexti8_i64:
; CHECK: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll b/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll
index c7902342f7f03..2a753f1d5a5d6 100644
--- a/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll
@@ -655,6 +655,44 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
ret i8 %sext
}
+; Make sure we don't use seqz+th.ext instead of snez+addi
+define signext i32 @sexti1_i32_setcc_2(i32 signext %a, i32 signext %b) {
+; RV64I-LABEL: sexti1_i32_setcc_2:
+; RV64I: # %bb.0:
+; RV64I-NEXT: xor a0, a0, a1
+; RV64I-NEXT: snez a0, a0
+; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: ret
+;
+; RV64XTHEADBB-LABEL: sexti1_i32_setcc_2:
+; RV64XTHEADBB: # %bb.0:
+; RV64XTHEADBB-NEXT: xor a0, a0, a1
+; RV64XTHEADBB-NEXT: seqz a0, a0
+; RV64XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV64XTHEADBB-NEXT: ret
+ %icmp = icmp eq i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
+
+; Make sure we don't use th.ext instead of neg.
+define signext i32 @sexti1_i32_setcc_3(i32 signext %a, i32 signext %b) {
+; RV64I-LABEL: sexti1_i32_setcc_3:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slt a0, a0, a1
+; RV64I-NEXT: neg a0, a0
+; RV64I-NEXT: ret
+;
+; RV64XTHEADBB-LABEL: sexti1_i32_setcc_3:
+; RV64XTHEADBB: # %bb.0:
+; RV64XTHEADBB-NEXT: slt a0, a0, a1
+; RV64XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV64XTHEADBB-NEXT: ret
+ %icmp = icmp slt i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
+
define i64 @sexti1_i64(i64 %a) nounwind {
; RV64I-LABEL: sexti1_i64:
; RV64I: # %bb.0:
@@ -706,6 +744,44 @@ define zeroext i8 @sexti1_i64_setcc(i64 %a) {
ret i8 %sext
}
+; Make sure we don't use seqz+th.ext instead of snez+addi
+define i64 @sexti1_i64_setcc_2(i64 %a, i64 %b) {
+; RV64I-LABEL: sexti1_i64_setcc_2:
+; RV64I: # %bb.0:
+; RV64I-NEXT: xor a0, a0, a1
+; RV64I-NEXT: snez a0, a0
+; RV64I-NEXT: addi a0, a0, -1
+; RV64I-NEXT: ret
+;
+; RV64XTHEADBB-LABEL: sexti1_i64_setcc_2:
+; RV64XTHEADBB: # %bb.0:
+; RV64XTHEADBB-NEXT: xor a0, a0, a1
+; RV64XTHEADBB-NEXT: seqz a0, a0
+; RV64XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV64XTHEADBB-NEXT: ret
+ %icmp = icmp eq i64 %a, %b
+ %sext = sext i1 %icmp to i64
+ ret i64 %sext
+}
+
+; Make sure we don't use th.ext instead of neg.
+define i64 @sexti1_i64_setcc_3(i64 %a, i64 %b) {
+; RV64I-LABEL: sexti1_i64_setcc_3:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slt a0, a0, a1
+; RV64I-NEXT: neg a0, a0
+; RV64I-NEXT: ret
+;
+; RV64XTHEADBB-LABEL: sexti1_i64_setcc_3:
+; RV64XTHEADBB: # %bb.0:
+; RV64XTHEADBB-NEXT: slt a0, a0, a1
+; RV64XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV64XTHEADBB-NEXT: ret
+ %icmp = icmp slt i64 %a, %b
+ %sext = sext i1 %icmp to i64
+ ret i64 %sext
+}
+
define signext i32 @sextb_i32(i32 signext %a) nounwind {
; RV64I-LABEL: sextb_i32:
; RV64I: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/xqcibm-extract.ll b/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
index fc3d8fe54602a..458414bef12cf 100644
--- a/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
+++ b/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
@@ -74,6 +74,56 @@ define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
ret i8 %sext
}
+; Make sure we don't use seqz+qc.ext instead of snez+addi
+define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
+; RV32I-LABEL: sexti1_i32_setcc_2:
+; RV32I: # %bb.0:
+; RV32I-NEXT: xor a0, a0, a1
+; RV32I-NEXT: snez a0, a0
+; RV32I-NEXT: addi a0, a0, -1
+; RV32I-NEXT: ret
+;
+; RV32XQCIBM-LABEL: sexti1_i32_setcc_2:
+; RV32XQCIBM: # %bb.0:
+; RV32XQCIBM-NEXT: xor a0, a0, a1
+; RV32XQCIBM-NEXT: seqz a0, a0
+; RV32XQCIBM-NEXT: qc.ext a0, a0, 1, 0
+; RV32XQCIBM-NEXT: ret
+;
+; RV32XQCIBMZBB-LABEL: sexti1_i32_setcc_2:
+; RV32XQCIBMZBB: # %bb.0:
+; RV32XQCIBMZBB-NEXT: xor a0, a0, a1
+; RV32XQCIBMZBB-NEXT: seqz a0, a0
+; RV32XQCIBMZBB-NEXT: qc.ext a0, a0, 1, 0
+; RV32XQCIBMZBB-NEXT: ret
+ %icmp = icmp eq i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
+
+; Make sure we don't use qc.ext instead of neg.
+define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {
+; RV32I-LABEL: sexti1_i32_setcc_3:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slt a0, a0, a1
+; RV32I-NEXT: neg a0, a0
+; RV32I-NEXT: ret
+;
+; RV32XQCIBM-LABEL: sexti1_i32_setcc_3:
+; RV32XQCIBM: # %bb.0:
+; RV32XQCIBM-NEXT: slt a0, a0, a1
+; RV32XQCIBM-NEXT: qc.ext a0, a0, 1, 0
+; RV32XQCIBM-NEXT: ret
+;
+; RV32XQCIBMZBB-LABEL: sexti1_i32_setcc_3:
+; RV32XQCIBMZBB: # %bb.0:
+; RV32XQCIBMZBB-NEXT: slt a0, a0, a1
+; RV32XQCIBMZBB-NEXT: qc.ext a0, a0, 1, 0
+; RV32XQCIBMZBB-NEXT: ret
+ %icmp = icmp slt i32 %a, %b
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+}
define i32 @sexti8_i32(i8 %a) nounwind {
; RV32I-LABEL: sexti8_i32:
>From db098730853642514ad76aae72381f4b63fe06b3 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 18 Aug 2025 14:15:55 -0700
Subject: [PATCH 2/4] [RISCV] Fold (sext_inreg (setcc), i1) -> (sub 0, (setcc).
This helsp the 3 vendor extensions that make sext_inreg i1 legal.
I'm delaying this until after LegalizeDAG since we normally have
sext_inreg i1 up until LegalizeDAG turns it into and+neg.
I also delayed the recently added (sext_inreg (xor (setcc), -1), i1) combine.
Though the xor isn't likely to appear before LegalizeDAG anyway.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 21 +++++++++++++--------
llvm/test/CodeGen/RISCV/rv32xandesperf.ll | 9 +++++----
llvm/test/CodeGen/RISCV/rv32xtheadbb.ll | 6 +++---
llvm/test/CodeGen/RISCV/rv64xandesperf.ll | 12 ++++++------
llvm/test/CodeGen/RISCV/rv64xtheadbb.ll | 12 ++++++------
llvm/test/CodeGen/RISCV/xqcibm-extract.ll | 12 ++++++------
6 files changed, 39 insertions(+), 33 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index ce03818b49502..a22ccda48dc82 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -16639,33 +16639,38 @@ static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG,
}
static SDValue
-performSIGN_EXTEND_INREGCombine(SDNode *N, SelectionDAG &DAG,
+performSIGN_EXTEND_INREGCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
const RISCVSubtarget &Subtarget) {
+ SelectionDAG &DAG = DCI.DAG;
SDValue Src = N->getOperand(0);
EVT VT = N->getValueType(0);
EVT SrcVT = cast<VTSDNode>(N->getOperand(1))->getVT();
unsigned Opc = Src.getOpcode();
+ SDLoc DL(N);
// Fold (sext_inreg (fmv_x_anyexth X), i16) -> (fmv_x_signexth X)
// Don't do this with Zhinx. We need to explicitly sign extend the GPR.
if (Opc == RISCVISD::FMV_X_ANYEXTH && SrcVT.bitsGE(MVT::i16) &&
Subtarget.hasStdExtZfhmin())
- return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, SDLoc(N), VT,
- Src.getOperand(0));
+ return DAG.getNode(RISCVISD::FMV_X_SIGNEXTH, DL, VT, Src.getOperand(0));
// Fold (sext_inreg (shl X, Y), i32) -> (sllw X, Y) iff Y u< 32
if (Opc == ISD::SHL && Subtarget.is64Bit() && SrcVT == MVT::i32 &&
VT == MVT::i64 && !isa<ConstantSDNode>(Src.getOperand(1)) &&
DAG.computeKnownBits(Src.getOperand(1)).countMaxActiveBits() <= 5)
- return DAG.getNode(RISCVISD::SLLW, SDLoc(N), VT, Src.getOperand(0),
+ return DAG.getNode(RISCVISD::SLLW, DL, VT, Src.getOperand(0),
Src.getOperand(1));
+ // Fold (sext_inreg (setcc), i1) -> (sub 0, (setcc)
+ if (Opc == ISD::SETCC && DCI.isAfterLegalizeDAG())
+ return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Src);
+
// Fold (sext_inreg (xor (setcc), -1), i1) -> (add (setcc), -1)
if (Opc == ISD::XOR && SrcVT == MVT::i1 &&
isAllOnesConstant(Src.getOperand(1)) &&
- Src.getOperand(0).getOpcode() == ISD::SETCC)
- return DAG.getNode(ISD::ADD, SDLoc(N), VT, Src.getOperand(0),
- DAG.getAllOnesConstant(SDLoc(N), VT));
+ Src.getOperand(0).getOpcode() == ISD::SETCC && DCI.isAfterLegalizeDAG())
+ return DAG.getNode(ISD::ADD, DL, VT, Src.getOperand(0),
+ DAG.getAllOnesConstant(DL, VT));
return SDValue();
}
@@ -20088,7 +20093,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
case ISD::SETCC:
return performSETCCCombine(N, DAG, Subtarget);
case ISD::SIGN_EXTEND_INREG:
- return performSIGN_EXTEND_INREGCombine(N, DAG, Subtarget);
+ return performSIGN_EXTEND_INREGCombine(N, DCI, Subtarget);
case ISD::ZERO_EXTEND:
// Fold (zero_extend (fp_to_uint X)) to prevent forming fcvt+zexti32 during
// type legalization. This is safe because fp_to_uint produces poison if
diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
index 45d1324495506..f93d7e093c696 100644
--- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -382,8 +382,8 @@ define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
; CHECK-LABEL: sexti1_i32_setcc_2:
; CHECK: # %bb.0:
; CHECK-NEXT: xor a0, a0, a1
-; CHECK-NEXT: seqz a0, a0
-; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: snez a0, a0
+; CHECK-NEXT: addi a0, a0, -1
; CHECK-NEXT: ret
%icmp = icmp eq i32 %a, %b
%sext = sext i1 %icmp to i32
@@ -394,8 +394,9 @@ define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {
; CHECK-LABEL: sexti1_i32_setcc_3:
; CHECK: # %bb.0:
-; CHECK-NEXT: slt a0, a0, a1
-; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: slt a1, a0, a1
+; CHECK-NEXT: li a0, 0
+; CHECK-NEXT: sub a0, a0, a1
; CHECK-NEXT: ret
%icmp = icmp slt i32 %a, %b
%sext = sext i1 %icmp to i32
diff --git a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
index 96db7e1e8e38f..0ccae67753f6b 100644
--- a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
@@ -346,8 +346,8 @@ define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
; RV32XTHEADBB-LABEL: sexti1_i32_setcc_2:
; RV32XTHEADBB: # %bb.0:
; RV32XTHEADBB-NEXT: xor a0, a0, a1
-; RV32XTHEADBB-NEXT: seqz a0, a0
-; RV32XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV32XTHEADBB-NEXT: snez a0, a0
+; RV32XTHEADBB-NEXT: addi a0, a0, -1
; RV32XTHEADBB-NEXT: ret
%icmp = icmp eq i32 %a, %b
%sext = sext i1 %icmp to i32
@@ -365,7 +365,7 @@ define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {
; RV32XTHEADBB-LABEL: sexti1_i32_setcc_3:
; RV32XTHEADBB: # %bb.0:
; RV32XTHEADBB-NEXT: slt a0, a0, a1
-; RV32XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV32XTHEADBB-NEXT: neg a0, a0
; RV32XTHEADBB-NEXT: ret
%icmp = icmp slt i32 %a, %b
%sext = sext i1 %icmp to i32
diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
index 00004ba516afb..225495817ae16 100644
--- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -295,8 +295,8 @@ define signext i32 @sexti1_i32_setcc_2(i32 signext %a, i32 signext %b) {
; CHECK-LABEL: sexti1_i32_setcc_2:
; CHECK: # %bb.0:
; CHECK-NEXT: xor a0, a0, a1
-; CHECK-NEXT: seqz a0, a0
-; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: snez a0, a0
+; CHECK-NEXT: addi a0, a0, -1
; CHECK-NEXT: ret
%icmp = icmp eq i32 %a, %b
%sext = sext i1 %icmp to i32
@@ -308,7 +308,7 @@ define signext i32 @sexti1_i32_setcc_3(i32 signext %a, i32 signext %b) {
; CHECK-LABEL: sexti1_i32_setcc_3:
; CHECK: # %bb.0:
; CHECK-NEXT: slt a0, a0, a1
-; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: neg a0, a0
; CHECK-NEXT: ret
%icmp = icmp slt i32 %a, %b
%sext = sext i1 %icmp to i32
@@ -390,8 +390,8 @@ define i64 @sexti1_i64_setcc_2(i64 %a, i64 %b) {
; CHECK-LABEL: sexti1_i64_setcc_2:
; CHECK: # %bb.0:
; CHECK-NEXT: xor a0, a0, a1
-; CHECK-NEXT: seqz a0, a0
-; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: snez a0, a0
+; CHECK-NEXT: addi a0, a0, -1
; CHECK-NEXT: ret
%icmp = icmp eq i64 %a, %b
%sext = sext i1 %icmp to i64
@@ -403,7 +403,7 @@ define i64 @sexti1_i64_setcc_3(i64 %a, i64 %b) {
; CHECK-LABEL: sexti1_i64_setcc_3:
; CHECK: # %bb.0:
; CHECK-NEXT: slt a0, a0, a1
-; CHECK-NEXT: nds.bfos a0, a0, 0, 0
+; CHECK-NEXT: neg a0, a0
; CHECK-NEXT: ret
%icmp = icmp slt i64 %a, %b
%sext = sext i1 %icmp to i64
diff --git a/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll b/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll
index 2a753f1d5a5d6..536217abd06c6 100644
--- a/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll
@@ -667,8 +667,8 @@ define signext i32 @sexti1_i32_setcc_2(i32 signext %a, i32 signext %b) {
; RV64XTHEADBB-LABEL: sexti1_i32_setcc_2:
; RV64XTHEADBB: # %bb.0:
; RV64XTHEADBB-NEXT: xor a0, a0, a1
-; RV64XTHEADBB-NEXT: seqz a0, a0
-; RV64XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV64XTHEADBB-NEXT: snez a0, a0
+; RV64XTHEADBB-NEXT: addi a0, a0, -1
; RV64XTHEADBB-NEXT: ret
%icmp = icmp eq i32 %a, %b
%sext = sext i1 %icmp to i32
@@ -686,7 +686,7 @@ define signext i32 @sexti1_i32_setcc_3(i32 signext %a, i32 signext %b) {
; RV64XTHEADBB-LABEL: sexti1_i32_setcc_3:
; RV64XTHEADBB: # %bb.0:
; RV64XTHEADBB-NEXT: slt a0, a0, a1
-; RV64XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV64XTHEADBB-NEXT: neg a0, a0
; RV64XTHEADBB-NEXT: ret
%icmp = icmp slt i32 %a, %b
%sext = sext i1 %icmp to i32
@@ -756,8 +756,8 @@ define i64 @sexti1_i64_setcc_2(i64 %a, i64 %b) {
; RV64XTHEADBB-LABEL: sexti1_i64_setcc_2:
; RV64XTHEADBB: # %bb.0:
; RV64XTHEADBB-NEXT: xor a0, a0, a1
-; RV64XTHEADBB-NEXT: seqz a0, a0
-; RV64XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV64XTHEADBB-NEXT: snez a0, a0
+; RV64XTHEADBB-NEXT: addi a0, a0, -1
; RV64XTHEADBB-NEXT: ret
%icmp = icmp eq i64 %a, %b
%sext = sext i1 %icmp to i64
@@ -775,7 +775,7 @@ define i64 @sexti1_i64_setcc_3(i64 %a, i64 %b) {
; RV64XTHEADBB-LABEL: sexti1_i64_setcc_3:
; RV64XTHEADBB: # %bb.0:
; RV64XTHEADBB-NEXT: slt a0, a0, a1
-; RV64XTHEADBB-NEXT: th.ext a0, a0, 0, 0
+; RV64XTHEADBB-NEXT: neg a0, a0
; RV64XTHEADBB-NEXT: ret
%icmp = icmp slt i64 %a, %b
%sext = sext i1 %icmp to i64
diff --git a/llvm/test/CodeGen/RISCV/xqcibm-extract.ll b/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
index 458414bef12cf..c2c9d077b2526 100644
--- a/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
+++ b/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
@@ -86,15 +86,15 @@ define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {
; RV32XQCIBM-LABEL: sexti1_i32_setcc_2:
; RV32XQCIBM: # %bb.0:
; RV32XQCIBM-NEXT: xor a0, a0, a1
-; RV32XQCIBM-NEXT: seqz a0, a0
-; RV32XQCIBM-NEXT: qc.ext a0, a0, 1, 0
+; RV32XQCIBM-NEXT: snez a0, a0
+; RV32XQCIBM-NEXT: addi a0, a0, -1
; RV32XQCIBM-NEXT: ret
;
; RV32XQCIBMZBB-LABEL: sexti1_i32_setcc_2:
; RV32XQCIBMZBB: # %bb.0:
; RV32XQCIBMZBB-NEXT: xor a0, a0, a1
-; RV32XQCIBMZBB-NEXT: seqz a0, a0
-; RV32XQCIBMZBB-NEXT: qc.ext a0, a0, 1, 0
+; RV32XQCIBMZBB-NEXT: snez a0, a0
+; RV32XQCIBMZBB-NEXT: addi a0, a0, -1
; RV32XQCIBMZBB-NEXT: ret
%icmp = icmp eq i32 %a, %b
%sext = sext i1 %icmp to i32
@@ -112,13 +112,13 @@ define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {
; RV32XQCIBM-LABEL: sexti1_i32_setcc_3:
; RV32XQCIBM: # %bb.0:
; RV32XQCIBM-NEXT: slt a0, a0, a1
-; RV32XQCIBM-NEXT: qc.ext a0, a0, 1, 0
+; RV32XQCIBM-NEXT: neg a0, a0
; RV32XQCIBM-NEXT: ret
;
; RV32XQCIBMZBB-LABEL: sexti1_i32_setcc_3:
; RV32XQCIBMZBB: # %bb.0:
; RV32XQCIBMZBB-NEXT: slt a0, a0, a1
-; RV32XQCIBMZBB-NEXT: qc.ext a0, a0, 1, 0
+; RV32XQCIBMZBB-NEXT: neg a0, a0
; RV32XQCIBMZBB-NEXT: ret
%icmp = icmp slt i32 %a, %b
%sext = sext i1 %icmp to i32
>From 2fd13723a167c742c7afa6b35cde692fae8b3971 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 18 Aug 2025 15:47:03 -0700
Subject: [PATCH 3/4] Update llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Co-authored-by: Sam Elliott <sam at lenary.co.uk>
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index a22ccda48dc82..4324d50a13708 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -16661,7 +16661,7 @@ performSIGN_EXTEND_INREGCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
return DAG.getNode(RISCVISD::SLLW, DL, VT, Src.getOperand(0),
Src.getOperand(1));
- // Fold (sext_inreg (setcc), i1) -> (sub 0, (setcc)
+ // Fold (sext_inreg (setcc), i1) -> (sub 0, (setcc))
if (Opc == ISD::SETCC && DCI.isAfterLegalizeDAG())
return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Src);
>From c65210c4ba63dab77bce02481491436c0e5f6a32 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 18 Aug 2025 17:51:14 -0700
Subject: [PATCH 4/4] fixup! Add missing SrcVT check.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4324d50a13708..8763f0091b8c2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -16662,7 +16662,7 @@ performSIGN_EXTEND_INREGCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
Src.getOperand(1));
// Fold (sext_inreg (setcc), i1) -> (sub 0, (setcc))
- if (Opc == ISD::SETCC && DCI.isAfterLegalizeDAG())
+ if (Opc == ISD::SETCC && SrcVT == MVT::i1 && DCI.isAfterLegalizeDAG())
return DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, DL, VT), Src);
// Fold (sext_inreg (xor (setcc), -1), i1) -> (add (setcc), -1)
More information about the llvm-commits
mailing list