Skip to content

[RISCV] Use QC_E_ADDI to improve codegen for icmp {eq, ne} with a constant #139558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 13, 2025

Conversation

svs-quic
Copy link
Contributor

Use the QC_E_ADDI instruction when the constant is not a signed 12 bit value but is a signed 26 bit one. Don't use it if a single LUI instruction can be used instead.

…stant

Use the QC_E_ADDI instruction when the constant is not a signed 12 bit value
but is a signed 26 bit one. Don't use it if a single LUI instruction can be used
instead.
@llvmbot
Copy link
Member

llvmbot commented May 12, 2025

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

Author: Sudharsan Veeravalli (svs-quic)

Changes

Use the QC_E_ADDI instruction when the constant is not a signed 12 bit value but is a signed 26 bit one. Don't use it if a single LUI instruction can be used instead.


Patch is 29.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/139558.diff

2 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp (+12)
  • (modified) llvm/test/CodeGen/RISCV/i32-icmp.ll (+443)
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 9648349d2ab76..9c36d4118780c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -2997,6 +2997,18 @@ bool RISCVDAGToDAGISel::selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal,
           0);
       return true;
     }
+    // Same as the addi case above but for larger immediates (signed 26-bit) use
+    // the QC_E_ADDI instruction from the Xqcilia extension, if available. Avoid
+    // anything which can be done with a single lui as it might be compressible.
+    if (Subtarget->hasVendorXqcilia() && isInt<26>(CVal) &&
+        (CVal & 0xFFF) != 0) {
+      Val = SDValue(
+          CurDAG->getMachineNode(
+              RISCV::QC_E_ADDI, DL, N->getValueType(0), LHS,
+              CurDAG->getSignedTargetConstant(-CVal, DL, N->getValueType(0))),
+          0);
+      return true;
+    }
   }
 
   // If nothing else we can XOR the LHS and RHS to produce zero if they are
diff --git a/llvm/test/CodeGen/RISCV/i32-icmp.ll b/llvm/test/CodeGen/RISCV/i32-icmp.ll
index 3cbebf309e35f..6e3e0fe39cca7 100644
--- a/llvm/test/CodeGen/RISCV/i32-icmp.ll
+++ b/llvm/test/CodeGen/RISCV/i32-icmp.ll
@@ -1,6 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s -check-prefix=RV32I
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+experimental-xqcilia < %s \
+; RUN:   | FileCheck %s -check-prefix=RV32XQCILIA
 
 define i32 @icmp_eq(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_eq:
@@ -8,6 +10,12 @@ define i32 @icmp_eq(i32 %a, i32 %b) nounwind {
 ; RV32I-NEXT:    xor a0, a0, a1
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_eq:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    xor a0, a0, a1
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp eq i32 %a, %b
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -19,6 +27,12 @@ define i32 @icmp_eq_constant(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a0, a0, -42
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_eq_constant:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    addi a0, a0, -42
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp eq i32 %a, 42
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -32,6 +46,12 @@ define i32 @icmp_eq_constant_2049(i32 %a) nounwind {
 ; RV32I-NEXT:    xor a0, a0, a1
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_eq_constant_2049:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    qc.e.addi a0, a0, -2049
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp eq i32 %a, 2049
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -43,6 +63,12 @@ define i32 @icmp_eq_constant_2048(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a0, a0, -2048
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_eq_constant_2048:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    addi a0, a0, -2048
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp eq i32 %a, 2048
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -54,6 +80,12 @@ define i32 @icmp_eq_constant_neg_2048(i32 %a) nounwind {
 ; RV32I-NEXT:    xori a0, a0, -2048
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_eq_constant_neg_2048:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    xori a0, a0, -2048
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp eq i32 %a, -2048
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -65,6 +97,12 @@ define i32 @icmp_eq_constant_neg_2047(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a0, a0, 2047
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_eq_constant_neg_2047:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    addi a0, a0, 2047
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp eq i32 %a, -2047
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -75,17 +113,66 @@ define i32 @icmp_eqz(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_eqz:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp eq i32 %a, 0
   %2 = zext i1 %1 to i32
   ret i32 %2
 }
 
+define i32 @icmp_eq_constant_neg_33554431(i32 %a) nounwind {
+; RV32I-LABEL: icmp_eq_constant_neg_33554431:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a1, 8192
+; RV32I-NEXT:    addi a1, a1, -1
+; RV32I-NEXT:    xor a0, a0, a1
+; RV32I-NEXT:    seqz a0, a0
+; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_eq_constant_neg_33554431:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    qc.e.addi a0, a0, -33554431
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
+  %1 = icmp eq i32 %a, 33554431
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
+define i32 @icmp_eq_constant_33554432(i32 %a) nounwind {
+; RV32I-LABEL: icmp_eq_constant_33554432:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a1, 8192
+; RV32I-NEXT:    xor a0, a0, a1
+; RV32I-NEXT:    seqz a0, a0
+; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_eq_constant_33554432:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    lui a1, 8192
+; RV32XQCILIA-NEXT:    xor a0, a0, a1
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
+  %1 = icmp eq i32 %a, 33554432
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
 define i32 @icmp_ne(i32 %a, i32 %b) nounwind {
 ; RV32I-LABEL: icmp_ne:
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    xor a0, a0, a1
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ne:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    xor a0, a0, a1
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ne i32 %a, %b
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -97,6 +184,12 @@ define i32 @icmp_ne_constant(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a0, a0, -42
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ne_constant:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    addi a0, a0, -42
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ne i32 %a, 42
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -110,6 +203,12 @@ define i32 @icmp_ne_constant_2049(i32 %a) nounwind {
 ; RV32I-NEXT:    xor a0, a0, a1
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ne_constant_2049:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    qc.e.addi a0, a0, -2049
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ne i32 %a, 2049
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -121,6 +220,12 @@ define i32 @icmp_ne_constant_2048(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a0, a0, -2048
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ne_constant_2048:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    addi a0, a0, -2048
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ne i32 %a, 2048
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -132,6 +237,12 @@ define i32 @icmp_ne_constant_neg_2048(i32 %a) nounwind {
 ; RV32I-NEXT:    xori a0, a0, -2048
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ne_constant_neg_2048:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    xori a0, a0, -2048
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ne i32 %a, -2048
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -143,16 +254,65 @@ define i32 @icmp_ne_constant_neg_2047(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a0, a0, 2047
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ne_constant_neg_2047:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    addi a0, a0, 2047
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ne i32 %a, -2047
   %2 = zext i1 %1 to i32
   ret i32 %2
 }
 
+define i32 @icmp_ne_constant_neg_33554431(i32 %a) nounwind {
+; RV32I-LABEL: icmp_ne_constant_neg_33554431:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a1, 8192
+; RV32I-NEXT:    addi a1, a1, -1
+; RV32I-NEXT:    xor a0, a0, a1
+; RV32I-NEXT:    snez a0, a0
+; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ne_constant_neg_33554431:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    qc.e.addi a0, a0, -33554431
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
+  %1 = icmp ne i32 %a, 33554431
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
+define i32 @icmp_ne_constant_33554432(i32 %a) nounwind {
+; RV32I-LABEL: icmp_ne_constant_33554432:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a1, 8192
+; RV32I-NEXT:    xor a0, a0, a1
+; RV32I-NEXT:    snez a0, a0
+; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ne_constant_33554432:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    lui a1, 8192
+; RV32XQCILIA-NEXT:    xor a0, a0, a1
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
+  %1 = icmp ne i32 %a, 33554432
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
 define i32 @icmp_nez(i32 %a) nounwind {
 ; RV32I-LABEL: icmp_nez:
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_nez:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ne i32 %a, 0
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -163,6 +323,11 @@ define i32 @icmp_ne_neg_1(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    sltiu a0, a0, -1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ne_neg_1:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltiu a0, a0, -1
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ne i32 %a, -1
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -173,6 +338,11 @@ define i32 @icmp_ugt(i32 %a, i32 %b) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    sltu a0, a1, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ugt:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltu a0, a1, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ugt i32 %a, %b
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -183,6 +353,11 @@ define i32 @icmp_ugt_constant_zero(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    snez a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ugt_constant_zero:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    snez a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ugt i32 %a, 0
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -194,6 +369,12 @@ define i32 @icmp_ugt_constant_2047(i32 %a) nounwind {
 ; RV32I-NEXT:    li a1, 2047
 ; RV32I-NEXT:    sltu a0, a1, 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:    ret
   %1 = icmp ugt i32 %a, 2047
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -205,6 +386,12 @@ define i32 @icmp_ugt_constant_2046(i32 %a) nounwind {
 ; RV32I-NEXT:    sltiu a0, a0, 2047
 ; RV32I-NEXT:    xori a0, a0, 1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ugt_constant_2046:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltiu a0, a0, 2047
+; RV32XQCILIA-NEXT:    xori a0, a0, 1
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ugt i32 %a, 2046
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -216,6 +403,12 @@ define i32 @icmp_ugt_constant_neg_2049(i32 %a) nounwind {
 ; RV32I-NEXT:    sltiu a0, a0, -2048
 ; RV32I-NEXT:    xori a0, a0, 1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ugt_constant_neg_2049:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltiu a0, a0, -2048
+; RV32XQCILIA-NEXT:    xori a0, a0, 1
+; RV32XQCILIA-NEXT:    ret
 ; 4294965247 signed extend is -2049
   %1 = icmp ugt i32 %a, 4294965247
   %2 = zext i1 %1 to i32
@@ -229,6 +422,13 @@ define i32 @icmp_ugt_constant_neg_2050(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a1, 2046
 ; RV32I-NEXT:    sltu a0, a1, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ugt_constant_neg_2050:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    lui a1, 1048575
+; RV32XQCILIA-NEXT:    addi a1, a1, 2046
+; RV32XQCILIA-NEXT:    sltu a0, a1, a0
+; RV32XQCILIA-NEXT:    ret
 ; 4294965246 signed extend is -2050
   %1 = icmp ugt i32 %a, 4294965246
   %2 = zext i1 %1 to i32
@@ -241,6 +441,12 @@ define i32 @icmp_uge(i32 %a, i32 %b) nounwind {
 ; RV32I-NEXT:    sltu a0, a0, a1
 ; RV32I-NEXT:    xori a0, a0, 1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_uge:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltu a0, a0, a1
+; RV32XQCILIA-NEXT:    xori a0, a0, 1
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp uge i32 %a, %b
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -251,6 +457,11 @@ define i32 @icmp_uge_constant_zero(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    li a0, 1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_uge_constant_zero:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    li a0, 1
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp uge i32 %a, 0
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -262,6 +473,12 @@ define i32 @icmp_uge_constant_2047(i32 %a) nounwind {
 ; RV32I-NEXT:    sltiu a0, a0, 2047
 ; RV32I-NEXT:    xori a0, a0, 1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_uge_constant_2047:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltiu a0, a0, 2047
+; RV32XQCILIA-NEXT:    xori a0, a0, 1
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp uge i32 %a, 2047
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -273,6 +490,12 @@ define i32 @icmp_uge_constant_2048(i32 %a) nounwind {
 ; RV32I-NEXT:    li a1, 2047
 ; RV32I-NEXT:    sltu a0, a1, 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:    ret
   %1 = icmp uge i32 %a, 2048
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -284,6 +507,12 @@ define i32 @icmp_uge_constant_neg_2048(i32 %a) nounwind {
 ; RV32I-NEXT:    sltiu a0, a0, -2048
 ; RV32I-NEXT:    xori a0, a0, 1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_uge_constant_neg_2048:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltiu a0, a0, -2048
+; RV32XQCILIA-NEXT:    xori a0, a0, 1
+; RV32XQCILIA-NEXT:    ret
 ; 4294965248 signed extend is -2048
   %1 = icmp uge i32 %a, 4294965248
   %2 = zext i1 %1 to i32
@@ -297,6 +526,13 @@ define i32 @icmp_uge_constant_neg_2049(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a1, 2046
 ; RV32I-NEXT:    sltu a0, a1, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_uge_constant_neg_2049:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    lui a1, 1048575
+; RV32XQCILIA-NEXT:    addi a1, a1, 2046
+; RV32XQCILIA-NEXT:    sltu a0, a1, a0
+; RV32XQCILIA-NEXT:    ret
 ; 4294965247 signed extend is -2049
   %1 = icmp uge i32 %a, 4294965247
   %2 = zext i1 %1 to i32
@@ -308,6 +544,11 @@ define i32 @icmp_ult(i32 %a, i32 %b) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    sltu a0, a0, a1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ult:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltu a0, a0, a1
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ult i32 %a, %b
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -318,6 +559,11 @@ define i32 @icmp_ult_constant_zero(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    li a0, 0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ult_constant_zero:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    li a0, 0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ult i32 %a, 0
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -328,6 +574,11 @@ define i32 @icmp_ult_constant_2047(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    sltiu a0, a0, 2047
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ult_constant_2047:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltiu a0, a0, 2047
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ult i32 %a, 2047
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -339,6 +590,12 @@ define i32 @icmp_ult_constant_2048(i32 %a) nounwind {
 ; RV32I-NEXT:    srli a0, a0, 11
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ult_constant_2048:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    srli a0, a0, 11
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ult i32 %a, 2048
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -349,6 +606,11 @@ define i32 @icmp_ult_constant_neg_2048(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    sltiu a0, a0, -2048
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ult_constant_neg_2048:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltiu a0, a0, -2048
+; RV32XQCILIA-NEXT:    ret
 ; 4294965248 signed extend is -2048
   %1 = icmp ult i32 %a, 4294965248
   %2 = zext i1 %1 to i32
@@ -362,6 +624,13 @@ define i32 @icmp_ult_constant_neg_2049(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a1, 2047
 ; RV32I-NEXT:    sltu a0, a0, a1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ult_constant_neg_2049:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    lui a1, 1048575
+; RV32XQCILIA-NEXT:    addi a1, a1, 2047
+; RV32XQCILIA-NEXT:    sltu a0, a0, a1
+; RV32XQCILIA-NEXT:    ret
 ; 4294965247 signed extend is -2049
   %1 = icmp ult i32 %a, 4294965247
   %2 = zext i1 %1 to i32
@@ -374,6 +643,12 @@ define i32 @icmp_ule(i32 %a, i32 %b) nounwind {
 ; RV32I-NEXT:    sltu a0, a1, a0
 ; RV32I-NEXT:    xori a0, a0, 1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ule:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltu a0, a1, a0
+; RV32XQCILIA-NEXT:    xori a0, a0, 1
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ule i32 %a, %b
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -384,6 +659,11 @@ define i32 @icmp_ule_constant_zero(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ule_constant_zero:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ule i32 %a, 0
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -394,6 +674,11 @@ define i32 @icmp_ule_constant_2046(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    sltiu a0, a0, 2047
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ule_constant_2046:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltiu a0, a0, 2047
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ule i32 %a, 2046
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -405,6 +690,12 @@ define i32 @icmp_ule_constant_2047(i32 %a) nounwind {
 ; RV32I-NEXT:    srli a0, a0, 11
 ; RV32I-NEXT:    seqz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ule_constant_2047:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    srli a0, a0, 11
+; RV32XQCILIA-NEXT:    seqz a0, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp ule i32 %a, 2047
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -415,6 +706,11 @@ define i32 @icmp_ule_constant_neg_2049(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    sltiu a0, a0, -2048
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ule_constant_neg_2049:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    sltiu a0, a0, -2048
+; RV32XQCILIA-NEXT:    ret
 ; 4294965247 signed extend is -2049
   %1 = icmp ule i32 %a, 4294965247
   %2 = zext i1 %1 to i32
@@ -428,6 +724,13 @@ define i32 @icmp_ule_constant_neg_2050(i32 %a) nounwind {
 ; RV32I-NEXT:    addi a1, a1, 2047
 ; RV32I-NEXT:    sltu a0, a0, a1
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_ule_constant_neg_2050:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    lui a1, 1048575
+; RV32XQCILIA-NEXT:    addi a1, a1, 2047
+; RV32XQCILIA-NEXT:    sltu a0, a0, a1
+; RV32XQCILIA-NEXT:    ret
 ; 4294965246 signed extend is -2050
   %1 = icmp ule i32 %a, 4294965246
   %2 = zext i1 %1 to i32
@@ -439,6 +742,11 @@ define i32 @icmp_sgt(i32 %a, i32 %b) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    slt a0, a1, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_sgt:
+; RV32XQCILIA:       # %bb.0:
+; RV32XQCILIA-NEXT:    slt a0, a1, a0
+; RV32XQCILIA-NEXT:    ret
   %1 = icmp sgt i32 %a, %b
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -449,6 +757,11 @@ define i32 @icmp_sgt_constant_zero(i32 %a) nounwind {
 ; RV32I:       # %bb.0:
 ; RV32I-NEXT:    sgtz a0, a0
 ; RV32I-NEXT:    ret
+;
+; RV32XQCILIA-LABEL: icmp_sgt_constant_zero:
+; RV32XQCILIA:       #...
[truncated]

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

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.

(I remain happy with this patch)

This might be a place where using qc.e.addai is also helpful, given a lot of the codegen we're seeing.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

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

LGTM

@svs-quic
Copy link
Contributor Author

(I remain happy with this patch)

This might be a place where using qc.e.addai is also helpful, given a lot of the codegen we're seeing.

Thanks but given that we're doing this early, I feel that keeping it as qc.addi might make it easier to register allocate for. Since both qc.addi and qc.e.addai are 6-bytes, the only cases we're missing out on are ones where the constant is !isInt<26>. I'd like to see how many such cases we hit before adding support for that.

@svs-quic svs-quic merged commit 595544b into llvm:main May 13, 2025
13 checks passed
@svs-quic svs-quic deleted the icmp_xqcilia branch May 13, 2025 02:59
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