Skip to content

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Aug 27, 2025

This matches 4095 and other pow2-1 constants larger simm12. We normally do this through a DAGCombine controlled by isLegalICmpImmediate. 2047 is considered a legal immediate because we have a setult instruction. In this case we have setugt which isn't natively supported.

I added tests for 4095 for comparison.

This matches 4095 and other pow2-1 constants larger simm12. We
normally do this through a DAGCombine controlled by
isLegalICmpImmediate. 2047 is considered a legal immediate because
we have a setult instruction. In this case we have setugt which
isn't natively supported.

I added tests for 4095 for comparison.
@llvmbot
Copy link
Member

llvmbot commented Aug 27, 2025

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

Author: Craig Topper (topperc)

Changes

This matches 4095 and other pow2-1 constants larger simm12. We normally do this through a DAGCombine controlled by isLegalICmpImmediate. 2047 is considered a legal immediate because we have a setult instruction. In this case we have setugt which isn't natively supported.

I added tests for 4095 for comparison.


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

3 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+7)
  • (modified) llvm/test/CodeGen/RISCV/i32-icmp.ll (+25-8)
  • (modified) llvm/test/CodeGen/RISCV/i64-icmp.ll (+17-6)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index b84bd1ce0ac50..6aa86741dcc1d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -8193,6 +8193,13 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
               DL, VT, LHS, DAG.getSignedConstant(Imm + 1, DL, OpVT), CCVal);
           return DAG.getLogicalNOT(DL, SetCC, VT);
         }
+        // Lower (setugt X, 2047) as (setne (srl X, 11), 0).
+        if (CCVal == ISD::SETUGT && Imm == 2047) {
+          SDValue Shift = DAG.getNode(ISD::SRL, DL, OpVT, LHS,
+                                      DAG.getShiftAmountConstant(11, OpVT, DL));
+          return DAG.getSetCC(DL, VT, Shift, DAG.getConstant(0, DL, OpVT),
+                              ISD::SETNE);
+        }
       }
 
       // Not a constant we could handle, swap the operands and condition code to
diff --git a/llvm/test/CodeGen/RISCV/i32-icmp.ll b/llvm/test/CodeGen/RISCV/i32-icmp.ll
index 53892f9497bba..5bc8b2333764e 100644
--- a/llvm/test/CodeGen/RISCV/i32-icmp.ll
+++ b/llvm/test/CodeGen/RISCV/i32-icmp.ll
@@ -366,20 +366,37 @@ define i32 @icmp_ugt_constant_zero(i32 %a) nounwind {
 define i32 @icmp_ugt_constant_2047(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_ugt_constant_2047:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    li a1, 2047
-; RV32I-NEXT:    sltu a0, a1, a0
+; RV32I-NEXT:    srli a0, a0, 11
+; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
 ;
 ; RV32XQCILIA-LABEL: icmp_ugt_constant_2047:
 ; RV32XQCILIA:       # %bb.0:
-; RV32XQCILIA-NEXT:    li a1, 2047
-; RV32XQCILIA-NEXT:    sltu a0, a1, a0
+; RV32XQCILIA-NEXT:    srli a0, a0, 11
+; RV32XQCILIA-NEXT:    snez a0, a0
 ; RV32XQCILIA-NEXT:    ret
   %1 = icmp ugt i32 %a, 2047
   %2 = zext i1 %1 to i32
   ret i32 %2
 }
 
+define i32 @icmp_ugt_constant_4095(i32 %a) nounwind {
+; RV32I-LABEL: icmp_ugt_constant_4095:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    srli a0, a0, 12
+; RV32I-NEXT:    snez a0, a0
+; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ugt_constant_4095:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    srli a0, a0, 12
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
+  %1 = icmp ugt i32 %a, 4095
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
 define i32 @icmp_ugt_constant_2046(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_ugt_constant_2046:
 ; RV32I:       # %bb.0:
@@ -487,14 +504,14 @@ define i32 @icmp_uge_constant_2047(i32 %a) nounwind {
 define i32 @icmp_uge_constant_2048(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_uge_constant_2048:
 ; RV32I:       # %bb.0:
-; RV32I-NEXT:    li a1, 2047
-; RV32I-NEXT:    sltu a0, a1, a0
+; RV32I-NEXT:    srli a0, a0, 11
+; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
 ;
 ; RV32XQCILIA-LABEL: icmp_uge_constant_2048:
 ; RV32XQCILIA:       # %bb.0:
-; RV32XQCILIA-NEXT:    li a1, 2047
-; RV32XQCILIA-NEXT:    sltu a0, a1, a0
+; RV32XQCILIA-NEXT:    srli a0, a0, 11
+; RV32XQCILIA-NEXT:    snez a0, a0
 ; RV32XQCILIA-NEXT:    ret
   %1 = icmp uge i32 %a, 2048
   %2 = zext i1 %1 to i32
diff --git a/llvm/test/CodeGen/RISCV/i64-icmp.ll b/llvm/test/CodeGen/RISCV/i64-icmp.ll
index 837987d8b9162..88d989daaa5cd 100644
--- a/llvm/test/CodeGen/RISCV/i64-icmp.ll
+++ b/llvm/test/CodeGen/RISCV/i64-icmp.ll
@@ -191,14 +191,25 @@ define i64 @icmp_ugt_constant_zero(i64 %a) nounwind {
 define i64 @icmp_ugt_constant_2047(i64 %a) nounwind {
 ; RV64I-LABEL: icmp_ugt_constant_2047:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    li a1, 2047
-; RV64I-NEXT:    sltu a0, a1, a0
+; RV64I-NEXT:    srli a0, a0, 11
+; RV64I-NEXT:    snez a0, a0
 ; RV64I-NEXT:    ret
   %1 = icmp ugt i64 %a, 2047
   %2 = zext i1 %1 to i64
   ret i64 %2
 }
 
+define i64 @icmp_ugt_constant_4095(i64 %a) nounwind {
+; RV64I-LABEL: icmp_ugt_constant_4095:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    srli a0, a0, 12
+; RV64I-NEXT:    snez a0, a0
+; RV64I-NEXT:    ret
+  %1 = icmp ugt i64 %a, 4095
+  %2 = zext i1 %1 to i64
+  ret i64 %2
+}
+
 define i64 @icmp_ugt_constant_2046(i64 %a) nounwind {
 ; RV64I-LABEL: icmp_ugt_constant_2046:
 ; RV64I:       # %bb.0:
@@ -270,8 +281,8 @@ define i64 @icmp_uge_constant_2047(i64 %a) nounwind {
 define i64 @icmp_uge_constant_2048(i64 %a) nounwind {
 ; RV64I-LABEL: icmp_uge_constant_2048:
 ; RV64I:       # %bb.0:
-; RV64I-NEXT:    li a1, 2047
-; RV64I-NEXT:    sltu a0, a1, a0
+; RV64I-NEXT:    srli a0, a0, 11
+; RV64I-NEXT:    snez a0, a0
 ; RV64I-NEXT:    ret
   %1 = icmp uge i64 %a, 2048
   %2 = zext i1 %1 to i64
@@ -754,10 +765,10 @@ define i64 @icmp_ne_zext_inreg_umin(i64 %a) nounwind {
 ; RV64I:       # %bb.0:
 ; RV64I-NEXT:    lui a1, 30141
 ; RV64I-NEXT:    addi a1, a1, -747
-; RV64I-NEXT:    bltu a0, a1, .LBB67_2
+; RV64I-NEXT:    bltu a0, a1, .LBB68_2
 ; RV64I-NEXT:  # %bb.1:
 ; RV64I-NEXT:    mv a0, a1
-; RV64I-NEXT:  .LBB67_2:
+; RV64I-NEXT:  .LBB68_2:
 ; RV64I-NEXT:    addi a0, a0, -123
 ; RV64I-NEXT:    snez a0, a0
 ; RV64I-NEXT:    ret

Copy link
Collaborator

@preames preames left a comment

Choose a reason for hiding this comment

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

LGTM

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.

@topperc topperc merged commit 5e587b1 into llvm:main Aug 27, 2025
11 checks passed
@topperc topperc deleted the pr/setugt-2047 branch August 27, 2025 06:05
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.

4 participants