Skip to content

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Aug 15, 2025

This improves all 3 vendor extensions that make sext_inreg i1 legal

Fixes #153781.

@llvmbot
Copy link
Member

llvmbot commented Aug 15, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

Changes

This improves all 3 vendor extensions that make sext_inreg i1 legal

Fixes #153781.


Full diff: https://github.com/llvm/llvm-project/pull/153855.diff

6 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+7)
  • (modified) llvm/test/CodeGen/RISCV/rv32xandesperf.ll (+13)
  • (modified) llvm/test/CodeGen/RISCV/rv32xtheadbb.ll (+20)
  • (modified) llvm/test/CodeGen/RISCV/rv64xandesperf.ll (+26)
  • (modified) llvm/test/CodeGen/RISCV/rv64xtheadbb.ll (+40)
  • (modified) llvm/test/CodeGen/RISCV/xqcibm-extract.ll (+27)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c5a706ae2b765..fbf02cad514b2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -16660,6 +16660,13 @@ performSIGN_EXTEND_INREGCombine(SDNode *N, SelectionDAG &DAG,
     return DAG.getNode(RISCVISD::SLLW, SDLoc(N), VT, Src.getOperand(0),
                        Src.getOperand(1));
 
+  // 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));
+
   return SDValue();
 }
 
diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
index 5cabb8c53e261..6f1d168358e2e 100644
--- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll
@@ -364,6 +364,19 @@ define i32 @sexti1_i32_2(i1 %a) {
   ret i32 %1
 }
 
+; Make sure we don't use not+nds.bfos
+define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
+; CHECK-LABEL: sexti1_i32_setcc:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    srli a0, a0, 31
+; CHECK-NEXT:    addi a0, a0, -1
+; CHECK-NEXT:    zext.b a0, a0
+; CHECK-NEXT:    ret
+  %icmp = icmp sgt i32 %a, -1
+  %sext = sext i1 %icmp to i8
+  ret i8 %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 723437a610ff8..784f08ca616cc 100644
--- a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll
@@ -314,6 +314,26 @@ define i32 @sexti1_i32_2(i1 %a) nounwind {
   ret i32 %sext
 }
 
+; Make sure we don't use not+th.ext
+define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
+; RV32I-LABEL: sexti1_i32_setcc:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    srli a0, a0, 31
+; RV32I-NEXT:    addi a0, a0, -1
+; RV32I-NEXT:    zext.b a0, a0
+; RV32I-NEXT:    ret
+;
+; RV32XTHEADBB-LABEL: sexti1_i32_setcc:
+; RV32XTHEADBB:       # %bb.0:
+; RV32XTHEADBB-NEXT:    srli a0, a0, 31
+; RV32XTHEADBB-NEXT:    addi a0, a0, -1
+; RV32XTHEADBB-NEXT:    zext.b a0, a0
+; RV32XTHEADBB-NEXT:    ret
+  %icmp = icmp sgt i32 %a, -1
+  %sext = sext i1 %icmp to i8
+  ret i8 %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 98cda42665169..406e5247ae0dd 100644
--- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll
@@ -277,6 +277,19 @@ define signext i32 @sexti1_i32_2(i1 %a) {
   ret i32 %1
 }
 
+; Make sure we don't use not+nds.bfos
+define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
+; CHECK-LABEL: sexti1_i32_setcc:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    srli a0, a0, 63
+; CHECK-NEXT:    addi a0, a0, -1
+; CHECK-NEXT:    zext.b a0, a0
+; CHECK-NEXT:    ret
+  %icmp = icmp sgt i32 %a, -1
+  %sext = sext i1 %icmp to i8
+  ret i8 %sext
+}
+
 define signext i32 @sexti8_i32(i32 signext %a) {
 ; CHECK-LABEL: sexti8_i32:
 ; CHECK:       # %bb.0:
@@ -334,6 +347,19 @@ define i64 @sexti1_i64_2(i1 %a) {
   ret i64 %1
 }
 
+; Make sure we don't use not+nds.bfos
+define zeroext i8 @sexti1_i64_setcc(i64 %a) {
+; CHECK-LABEL: sexti1_i64_setcc:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    srli a0, a0, 63
+; CHECK-NEXT:    addi a0, a0, -1
+; CHECK-NEXT:    zext.b a0, a0
+; CHECK-NEXT:    ret
+  %icmp = icmp sgt i64 %a, -1
+  %sext = sext i1 %icmp to i8
+  ret i8 %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 81acb4f724136..c7902342f7f03 100644
--- a/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll
@@ -635,6 +635,26 @@ define signext i32 @sexti1_i32_2(i1 %a) nounwind {
   ret i32 %sext
 }
 
+; Make sure we don't use not+th.ext
+define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
+; RV64I-LABEL: sexti1_i32_setcc:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    srli a0, a0, 63
+; RV64I-NEXT:    addi a0, a0, -1
+; RV64I-NEXT:    zext.b a0, a0
+; RV64I-NEXT:    ret
+;
+; RV64XTHEADBB-LABEL: sexti1_i32_setcc:
+; RV64XTHEADBB:       # %bb.0:
+; RV64XTHEADBB-NEXT:    srli a0, a0, 63
+; RV64XTHEADBB-NEXT:    addi a0, a0, -1
+; RV64XTHEADBB-NEXT:    zext.b a0, a0
+; RV64XTHEADBB-NEXT:    ret
+  %icmp = icmp sgt i32 %a, -1
+  %sext = sext i1 %icmp to i8
+  ret i8 %sext
+}
+
 define i64 @sexti1_i64(i64 %a) nounwind {
 ; RV64I-LABEL: sexti1_i64:
 ; RV64I:       # %bb.0:
@@ -666,6 +686,26 @@ define i64 @sexti1_i64_2(i1 %a) nounwind {
   ret i64 %sext
 }
 
+; Make sure we don't use not+th.ext
+define zeroext i8 @sexti1_i64_setcc(i64 %a) {
+; RV64I-LABEL: sexti1_i64_setcc:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    srli a0, a0, 63
+; RV64I-NEXT:    addi a0, a0, -1
+; RV64I-NEXT:    zext.b a0, a0
+; RV64I-NEXT:    ret
+;
+; RV64XTHEADBB-LABEL: sexti1_i64_setcc:
+; RV64XTHEADBB:       # %bb.0:
+; RV64XTHEADBB-NEXT:    srli a0, a0, 63
+; RV64XTHEADBB-NEXT:    addi a0, a0, -1
+; RV64XTHEADBB-NEXT:    zext.b a0, a0
+; RV64XTHEADBB-NEXT:    ret
+  %icmp = icmp sgt i64 %a, -1
+  %sext = sext i1 %icmp to i8
+  ret i8 %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 481bfdd666430..fc3d8fe54602a 100644
--- a/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
+++ b/llvm/test/CodeGen/RISCV/xqcibm-extract.ll
@@ -47,6 +47,33 @@ define i32 @sexti1_i32_2(i32 %a) {
   ret i32 %shr
 }
 
+; Make sure we don't use not+qc.ext
+define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {
+; RV32I-LABEL: sexti1_i32_setcc:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    srli a0, a0, 31
+; RV32I-NEXT:    addi a0, a0, -1
+; RV32I-NEXT:    zext.b a0, a0
+; RV32I-NEXT:    ret
+;
+; RV32XQCIBM-LABEL: sexti1_i32_setcc:
+; RV32XQCIBM:       # %bb.0:
+; RV32XQCIBM-NEXT:    srli a0, a0, 31
+; RV32XQCIBM-NEXT:    addi a0, a0, -1
+; RV32XQCIBM-NEXT:    qc.extu a0, a0, 8, 0
+; RV32XQCIBM-NEXT:    ret
+;
+; RV32XQCIBMZBB-LABEL: sexti1_i32_setcc:
+; RV32XQCIBMZBB:       # %bb.0:
+; RV32XQCIBMZBB-NEXT:    srli a0, a0, 31
+; RV32XQCIBMZBB-NEXT:    addi a0, a0, -1
+; RV32XQCIBMZBB-NEXT:    qc.extu a0, a0, 8, 0
+; RV32XQCIBMZBB-NEXT:    ret
+  %icmp = icmp sgt i32 %a, -1
+  %sext = sext i1 %icmp to i8
+  ret i8 %sext
+}
+
 
 define i32 @sexti8_i32(i8 %a) nounwind {
 ; RV32I-LABEL: sexti8_i32:

Copy link
Member

@lenary lenary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks

@topperc topperc merged commit c84a43f into llvm:main Aug 15, 2025
11 checks passed
@topperc topperc deleted the pr/sextinregi1 branch August 15, 2025 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RISC-V] Unprofitable use of th.ext insn for clamping

3 participants