[llvm] [RISCV] Support uimm5 operands for Xqcicm cmovs (PR #210955)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 21 04:43:38 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: Sudharsan Veeravalli (svs-quic)

<details>
<summary>Changes</summary>

`expandCCOpToCMov` was only accepting signed 5-bit immediates before forming `Xqcicm` conditional-move pseudos. Valid `uimm5` operands for unsigned compare forms such as `QC_MVGEUI` and `QC_MVLTUI` were not being handled  leading to a crash.

Track whether the selected conditional-move opcode expects a signed or unsigned immediate, and validate the RHS against the matching range.

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


3 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp (+10-1) 
- (modified) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_uge.ll (+20) 
- (modified) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_ult.ll (+20) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index a716d5206e556..7d679909a0b43 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -353,6 +353,7 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
   // Use branch opcode to select appropriate Xqcicm instruction
   unsigned BCC = MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
   std::optional<unsigned> CMovRegOpcode;
+  bool IsSigned = true;
   unsigned CMovImmOpcode;
   switch (BCC) {
   default:
@@ -376,10 +377,12 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
   case RISCV::BGEU:
     CMovRegOpcode = RISCV::QC_MVLTU;
     CMovImmOpcode = RISCV::QC_MVLTUI;
+    IsSigned = false;
     break;
   case RISCV::BLTU:
     CMovRegOpcode = RISCV::QC_MVGEU;
     CMovImmOpcode = RISCV::QC_MVGEUI;
+    IsSigned = false;
     break;
   case RISCV::QC_BEQI:
     CMovImmOpcode = RISCV::QC_MVNEI;
@@ -395,13 +398,19 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
     break;
   case RISCV::QC_BLTUI:
     CMovImmOpcode = RISCV::QC_MVGEUI;
+    IsSigned = false;
     break;
   case RISCV::QC_BGEUI:
     CMovImmOpcode = RISCV::QC_MVLTUI;
+    IsSigned = false;
     break;
   }
 
-  if (RHS.isImm() && isInt<5>(RHS.getImm())) {
+  if (RHS.isImm()) {
+    if ((!isInt<5>(RHS.getImm()) || !IsSigned) &&
+        (!isUInt<5>(RHS.getImm()) || IsSigned))
+      return false;
+
     // $dst = PseudoCCMOVGPR $falsev(=$dst), $truev, $opcode, $lhs, $rhs_imm
     // $dst = PseudoCCMOVGPRNoX0 $falsev(=$dst), $truev, $opcode, $lhs, $rhs_imm
     // =>
diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_uge.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_uge.ll
index 2351a0ff5185f..1c8040e72c8a3 100644
--- a/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_uge.ll
+++ b/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_uge.ll
@@ -893,3 +893,23 @@ entry:
   %res = select i1 %x, i32 %val, i32 %b
   ret i32 %res
 }
+
+define i32 @branch_with_uimmSFB_mv(i32 %a, i32 %c, i32 %d) {
+; RV32I-LABEL: branch_with_uimmSFB_mv:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a3, 26
+; RV32I-NEXT:    bltu a3, a2, .LBB34_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a1
+; RV32I-NEXT:  .LBB34_2: # %entry
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_uimmSFB_mv:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.mvltui a0, a2, 27, a1
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp uge i32 %d, 27
+  %sel = select i1 %x, i32 %a, i32 %c
+  ret i32 %sel
+}
diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_ult.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_ult.ll
index 0a52fc4757c06..bf489ff670b48 100644
--- a/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_ult.ll
+++ b/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_ult.ll
@@ -893,3 +893,23 @@ entry:
   %res = select i1 %x, i32 %val, i32 %b
   ret i32 %res
 }
+
+define i32 @branch_with_uimmSFB_mv(i32 %a, i32 %c, i32 %d) {
+; RV32I-LABEL: branch_with_uimmSFB_mv:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a3, 24
+; RV32I-NEXT:    bltu a2, a3, .LBB34_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a1
+; RV32I-NEXT:  .LBB34_2: # %entry
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_uimmSFB_mv:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.mvgeui a0, a2, 24, a1
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp ult i32 %d, 24
+  %sel = select i1 %x, i32 %a, i32 %c
+  ret i32 %sel
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/210955


More information about the llvm-commits mailing list