[llvm] [RISCV] Add isel patterns for generating Xqcibi branch instructions (PR #139872)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 14 03:19:25 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: Sudharsan Veeravalli (svs-quic)

<details>
<summary>Changes</summary>

Add ISEL patterns for generating the Xqcibi branch immediate instructions. Similar to #<!-- -->135771 adds new CondCodes for the various branch instructions and uses them to return the appropriate instruction.

---

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


5 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+22) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+96) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.h (+12) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+92) 
- (added) llvm/test/CodeGen/RISCV/xqcibi.ll (+359) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c01496c9a7f3a..282b848c9a330 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2389,6 +2389,8 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
 
   if (auto *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
     int64_t C = RHSC->getSExtValue();
+    const RISCVSubtarget &Subtarget =
+        DAG.getMachineFunction().getSubtarget<RISCVSubtarget>();
     switch (CC) {
     default: break;
     case ISD::SETGT:
@@ -2398,6 +2400,13 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
         CC = ISD::SETGE;
         return;
       }
+      if (Subtarget.hasVendorXqcibi() && isInt<16>(C + 1)) {
+        // We have a branch immediate instruction for SETGE but not SETGT.
+        // Convert X > C to X >= C + 1, if (C + 1) is a 16-bit signed immediate.
+        RHS = DAG.getSignedConstant(C + 1, DL, RHS.getValueType());
+        CC = ISD::SETGE;
+        return;
+      }
       break;
     case ISD::SETLT:
       // Convert X < 1 to 0 >= X.
@@ -2408,6 +2417,15 @@ static void translateSetCCForBranch(const SDLoc &DL, SDValue &LHS, SDValue &RHS,
         return;
       }
       break;
+    case ISD::SETUGT:
+      if (Subtarget.hasVendorXqcibi() && isInt<16>(C + 1) && C != -1) {
+        // We have a branch immediate instruction for SETUGE but not SETUGT.
+        // Convert X > C to X >= C + 1, if (C + 1) is a 16-bit signed immediate.
+        RHS = DAG.getSignedConstant(C + 1, DL, RHS.getValueType());
+        CC = ISD::SETUGE;
+        return;
+      }
+      break;
     }
   }
 
@@ -21203,6 +21221,10 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
     return emitReadCounterWidePseudo(MI, BB);
   case RISCV::Select_GPR_Using_CC_GPR:
   case RISCV::Select_GPR_Using_CC_Imm:
+  case RISCV::Select_GPR_Using_CC_Simm5NonZero:
+  case RISCV::Select_GPR_Using_CC_Uimm5NonZero:
+  case RISCV::Select_GPR_Using_CC_Simm16NonZero:
+  case RISCV::Select_GPR_Using_CC_Uimm16NonZero:
   case RISCV::Select_FPR16_Using_CC_GPR:
   case RISCV::Select_FPR16INX_Using_CC_GPR:
   case RISCV::Select_FPR32_Using_CC_GPR:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index f181c1e137545..a4f33546b01ac 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -993,6 +993,30 @@ static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc) {
     return RISCVCC::COND_CV_BEQIMM;
   case RISCV::CV_BNEIMM:
     return RISCVCC::COND_CV_BNEIMM;
+  case RISCV::QC_BEQI:
+    return RISCVCC::COND_QC_BEQI;
+  case RISCV::QC_E_BEQI:
+    return RISCVCC::COND_QC_E_BEQI;
+  case RISCV::QC_BNEI:
+    return RISCVCC::COND_QC_BNEI;
+  case RISCV::QC_E_BNEI:
+    return RISCVCC::COND_QC_E_BNEI;
+  case RISCV::QC_BLTI:
+    return RISCVCC::COND_QC_BLTI;
+  case RISCV::QC_E_BLTI:
+    return RISCVCC::COND_QC_E_BLTI;
+  case RISCV::QC_BGEI:
+    return RISCVCC::COND_QC_BGEI;
+  case RISCV::QC_E_BGEI:
+    return RISCVCC::COND_QC_E_BGEI;
+  case RISCV::QC_BLTUI:
+    return RISCVCC::COND_QC_BLTUI;
+  case RISCV::QC_E_BLTUI:
+    return RISCVCC::COND_QC_E_BLTUI;
+  case RISCV::QC_BGEUI:
+    return RISCVCC::COND_QC_BGEUI;
+  case RISCV::QC_E_BGEUI:
+    return RISCVCC::COND_QC_E_BGEUI;
   }
 }
 
@@ -1050,6 +1074,30 @@ unsigned RISCVCC::getBrCond(RISCVCC::CondCode CC) {
     return RISCV::CV_BEQIMM;
   case RISCVCC::COND_CV_BNEIMM:
     return RISCV::CV_BNEIMM;
+  case RISCVCC::COND_QC_BEQI:
+    return RISCV::QC_BEQI;
+  case RISCVCC::COND_QC_E_BEQI:
+    return RISCV::QC_E_BEQI;
+  case RISCVCC::COND_QC_BNEI:
+    return RISCV::QC_BNEI;
+  case RISCVCC::COND_QC_E_BNEI:
+    return RISCV::QC_E_BNEI;
+  case RISCVCC::COND_QC_BLTI:
+    return RISCV::QC_BLTI;
+  case RISCVCC::COND_QC_E_BLTI:
+    return RISCV::QC_E_BLTI;
+  case RISCVCC::COND_QC_BGEI:
+    return RISCV::QC_BGEI;
+  case RISCVCC::COND_QC_E_BGEI:
+    return RISCV::QC_E_BGEI;
+  case RISCVCC::COND_QC_BLTUI:
+    return RISCV::QC_BLTUI;
+  case RISCVCC::COND_QC_E_BLTUI:
+    return RISCV::QC_E_BLTUI;
+  case RISCVCC::COND_QC_BGEUI:
+    return RISCV::QC_BGEUI;
+  case RISCVCC::COND_QC_E_BGEUI:
+    return RISCV::QC_E_BGEUI;
   }
 }
 
@@ -1077,6 +1125,30 @@ RISCVCC::CondCode RISCVCC::getOppositeBranchCondition(RISCVCC::CondCode CC) {
     return RISCVCC::COND_CV_BNEIMM;
   case RISCVCC::COND_CV_BNEIMM:
     return RISCVCC::COND_CV_BEQIMM;
+  case RISCVCC::COND_QC_BEQI:
+    return RISCVCC::COND_QC_BNEI;
+  case RISCVCC::COND_QC_E_BEQI:
+    return RISCVCC::COND_QC_E_BNEI;
+  case RISCVCC::COND_QC_BNEI:
+    return RISCVCC::COND_QC_BEQI;
+  case RISCVCC::COND_QC_E_BNEI:
+    return RISCVCC::COND_QC_E_BEQI;
+  case RISCVCC::COND_QC_BLTI:
+    return RISCVCC::COND_QC_BGEI;
+  case RISCVCC::COND_QC_E_BLTI:
+    return RISCVCC::COND_QC_E_BGEI;
+  case RISCVCC::COND_QC_BGEI:
+    return RISCVCC::COND_QC_BLTI;
+  case RISCVCC::COND_QC_E_BGEI:
+    return RISCVCC::COND_QC_E_BLTI;
+  case RISCVCC::COND_QC_BLTUI:
+    return RISCVCC::COND_QC_BGEUI;
+  case RISCVCC::COND_QC_E_BLTUI:
+    return RISCVCC::COND_QC_E_BGEUI;
+  case RISCVCC::COND_QC_BGEUI:
+    return RISCVCC::COND_QC_BLTUI;
+  case RISCVCC::COND_QC_E_BGEUI:
+    return RISCVCC::COND_QC_E_BLTUI;
   }
 }
 
@@ -1452,6 +1524,18 @@ bool RISCVInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
   case RISCV::BGEU:
   case RISCV::CV_BEQIMM:
   case RISCV::CV_BNEIMM:
+  case RISCV::QC_BEQI:
+  case RISCV::QC_BNEI:
+  case RISCV::QC_BGEI:
+  case RISCV::QC_BLTI:
+  case RISCV::QC_BLTUI:
+  case RISCV::QC_BGEUI:
+  case RISCV::QC_E_BEQI:
+  case RISCV::QC_E_BNEI:
+  case RISCV::QC_E_BGEI:
+  case RISCV::QC_E_BLTI:
+  case RISCV::QC_E_BLTUI:
+  case RISCV::QC_E_BGEUI:
     return isIntN(13, BrOffset);
   case RISCV::JAL:
   case RISCV::PseudoBR:
@@ -2633,6 +2717,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
         case RISCVOp::OPERAND_UIMM5_LSB0:
           Ok = isShiftedUInt<4, 1>(Imm);
           break;
+        case RISCVOp::OPERAND_UIMM5_NONZERO:
+          Ok = isUInt<5>(Imm) && (Imm != 0);
+          break;
         case RISCVOp::OPERAND_UIMM6_LSB0:
           Ok = isShiftedUInt<5, 1>(Imm);
           break;
@@ -2660,6 +2747,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
         case RISCVOp::OPERAND_UIMM10_LSB00_NONZERO:
           Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
           break;
+        case RISCVOp::OPERAND_UIMM16_NONZERO:
+          Ok = isUInt<16>(Imm) && (Imm != 0);
+          break;
         case RISCVOp::OPERAND_ZERO:
           Ok = Imm == 0;
           break;
@@ -2679,6 +2769,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
         case RISCVOp::OPERAND_SIMM5_PLUS1:
           Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16;
           break;
+        case RISCVOp::OPERAND_SIMM5_NONZERO:
+          Ok = isInt<5>(Imm) && (Imm != 0);
+          break;
         case RISCVOp::OPERAND_SIMM6_NONZERO:
           Ok = Imm != 0 && isInt<6>(Imm);
           break;
@@ -2691,6 +2784,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
         case RISCVOp::OPERAND_SIMM12_LSB00000:
           Ok = isShiftedInt<7, 5>(Imm);
           break;
+        case RISCVOp::OPERAND_SIMM16_NONZERO:
+          Ok = isInt<16>(Imm) && (Imm != 0);
+          break;
         case RISCVOp::OPERAND_SIMM20_LI:
           Ok = isInt<20>(Imm);
           break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index 1ec6eed82469e..b099acd81e995 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -43,6 +43,18 @@ enum CondCode {
   COND_GEU,
   COND_CV_BEQIMM,
   COND_CV_BNEIMM,
+  COND_QC_BEQI,
+  COND_QC_BNEI,
+  COND_QC_BLTI,
+  COND_QC_BGEI,
+  COND_QC_BLTUI,
+  COND_QC_BGEUI,
+  COND_QC_E_BEQI,
+  COND_QC_E_BNEI,
+  COND_QC_E_BLTI,
+  COND_QC_E_BGEI,
+  COND_QC_E_BLTUI,
+  COND_QC_E_BGEUI,
   COND_INVALID
 };
 
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 57c1e999ac366..5e8f8f2956dc0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -188,6 +188,36 @@ def AddLike: PatFrags<(ops node:$A, node:$B),
 def AddShl : PatFrag<(ops node:$Ra, node:$Rb, node:$SH3),
                      (add node:$Ra, (shl node:$Rb, node:$SH3))>;
 
+def IntCCtoQCRISCVCC : SDNodeXForm<riscv_selectcc, [{
+  ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+  int64_t Imm = dyn_cast<ConstantSDNode>(N->getOperand(1))->getSExtValue();
+  RISCVCC::CondCode BrCC;
+  switch (CC) {
+  default:
+   report_fatal_error("Unexpected CondCode for Xqcibi branch instructions");
+  case ISD::SETEQ:
+    BrCC = isInt<5>(Imm) ? RISCVCC::COND_QC_BEQI :  RISCVCC::COND_QC_E_BEQI;
+    break;
+  case ISD::SETNE:
+    BrCC = isInt<5>(Imm) ? RISCVCC::COND_QC_BNEI :  RISCVCC::COND_QC_E_BNEI;
+    break;
+  case ISD::SETLT:
+    BrCC = isInt<5>(Imm) ? RISCVCC::COND_QC_BLTI :  RISCVCC::COND_QC_E_BLTI;
+    break;
+  case ISD::SETGE:
+    BrCC = isInt<5>(Imm) ? RISCVCC::COND_QC_BGEI :  RISCVCC::COND_QC_E_BGEI;
+    break;
+  case ISD::SETULT:
+    BrCC = isUInt<5>(Imm) ? RISCVCC::COND_QC_BLTUI :  RISCVCC::COND_QC_E_BLTUI;
+    break;
+  case ISD::SETUGE:
+    BrCC = isUInt<5>(Imm) ? RISCVCC::COND_QC_BGEUI :  RISCVCC::COND_QC_E_BGEUI;
+    break;
+  }
+  return CurDAG->getTargetConstant(BrCC, SDLoc(N), Subtarget->getXLenVT());
+}]>;
+
+
 //===----------------------------------------------------------------------===//
 // Instruction Formats
 //===----------------------------------------------------------------------===//
@@ -1288,6 +1318,36 @@ class QCScaledStPat<PatFrag StoreOp, RVInst Inst>
     : Pat<(StoreOp (i32 GPR:$rd), (AddShl (i32 GPRMem:$rs1), (i32 GPRNoX0:$rs2), uimm3:$shamt)),
           (Inst GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt)>;
 
+// Match `riscv_brcc` and lower to the appropriate XQCIBI branch instruction.
+class BcciPat<CondCode Cond, QCIBranchInst_rii Inst, DAGOperand InTyImm>
+    : Pat<(riscv_brcc (XLenVT GPRNoX0:$rs1), InTyImm:$rs2, Cond, bb:$imm12),
+          (Inst GPRNoX0:$rs1, InTyImm:$rs2, bare_simm13_lsb0:$imm12)>;
+
+class Bcci48Pat<CondCode Cond, QCIBranchInst48_rii Inst, DAGOperand InTyImm>
+    : Pat<(riscv_brcc (XLenVT GPRNoX0:$rs1), InTyImm:$rs2, Cond, bb:$imm12),
+          (Inst GPRNoX0:$rs1, InTyImm:$rs2, bare_simm13_lsb0:$imm12)>;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0, usesCustomInserter = 1 in {
+  def Select_GPR_Using_CC_Simm5NonZero : Pseudo<(outs GPR:$dst),
+                                                (ins GPR:$lhs, simm5nonzero:$imm5,
+                                                 cond_code:$cc, GPR:$truev, GPR:$falsev), []>;
+  def Select_GPR_Using_CC_Uimm5NonZero : Pseudo<(outs GPR:$dst),
+                                                (ins GPR:$lhs, uimm5nonzero:$imm5,
+                                                 cond_code:$cc, GPR:$truev, GPR:$falsev), []>;
+  def Select_GPR_Using_CC_Simm16NonZero : Pseudo<(outs GPR:$dst),
+                                                 (ins GPR:$lhs, simm16nonzero:$imm16,
+                                                  cond_code:$cc, GPR:$truev, GPR:$falsev), []>;
+  def Select_GPR_Using_CC_Uimm16NonZero : Pseudo<(outs GPR:$dst),
+                                                 (ins GPR:$lhs, uimm16nonzero:$imm16,
+                                                  cond_code:$cc, GPR:$truev, GPR:$falsev), []>;
+}
+
+class SelectQCbi<CondCode Cond, DAGOperand InTyImm, Pseudo OpNode >
+    : Pat<(riscv_selectcc_frag:$cc (i32 GPR:$lhs), InTyImm:$Constant, Cond,
+                                   (i32 GPR:$truev), GPR:$falsev),
+          (OpNode GPR:$lhs, InTyImm:$Constant,
+           (IntCCtoQCRISCVCC $cc), GPR:$truev, GPR:$falsev)>;
+
 /// Simple arithmetic operations
 
 let Predicates = [HasVendorXqcilia, IsRV32] in {
@@ -1342,6 +1402,38 @@ def : PatGprNoX0GprNoX0<ushlsat, QC_SHLUSAT>;
 def : PatGprNoX0GprNoX0<sshlsat, QC_SHLSAT>;
 } // Predicates = [HasVendorXqcia, IsRV32]
 
+/// Branches
+
+let Predicates = [HasVendorXqcibi, IsRV32], AddedComplexity = 2 in {
+def : BcciPat<SETEQ, QC_BEQI, simm5nonzero>;
+def : BcciPat<SETNE, QC_BNEI, simm5nonzero>;
+def : BcciPat<SETLT, QC_BLTI, simm5nonzero>;
+def : BcciPat<SETGE, QC_BGEI, simm5nonzero>;
+def : BcciPat<SETULT, QC_BLTUI, uimm5nonzero>;
+def : BcciPat<SETUGE, QC_BGEUI, uimm5nonzero>;
+
+def : Bcci48Pat<SETEQ, QC_E_BEQI, simm16nonzero>;
+def : Bcci48Pat<SETNE, QC_E_BNEI, simm16nonzero>;
+def : Bcci48Pat<SETLT, QC_E_BLTI, simm16nonzero>;
+def : Bcci48Pat<SETGE, QC_E_BGEI, simm16nonzero>;
+def : Bcci48Pat<SETULT, QC_E_BLTUI, uimm16nonzero>;
+def : Bcci48Pat<SETUGE, QC_E_BGEUI, uimm16nonzero>;
+
+def : SelectQCbi<SETEQ, simm5nonzero, Select_GPR_Using_CC_Simm5NonZero>;
+def : SelectQCbi<SETNE, simm5nonzero, Select_GPR_Using_CC_Simm5NonZero>;
+def : SelectQCbi<SETLT, simm5nonzero, Select_GPR_Using_CC_Simm5NonZero>;
+def : SelectQCbi<SETGE, simm5nonzero, Select_GPR_Using_CC_Simm5NonZero>;
+def : SelectQCbi<SETULT, uimm5nonzero, Select_GPR_Using_CC_Uimm5NonZero>;
+def : SelectQCbi<SETUGE, uimm5nonzero, Select_GPR_Using_CC_Uimm5NonZero>;
+
+def : SelectQCbi<SETEQ, simm16nonzero, Select_GPR_Using_CC_Simm16NonZero>;
+def : SelectQCbi<SETNE, simm16nonzero, Select_GPR_Using_CC_Simm16NonZero>;
+def : SelectQCbi<SETLT, simm16nonzero, Select_GPR_Using_CC_Simm16NonZero>;
+def : SelectQCbi<SETGE, simm16nonzero, Select_GPR_Using_CC_Simm16NonZero>;
+def : SelectQCbi<SETULT, uimm16nonzero, Select_GPR_Using_CC_Uimm16NonZero>;
+def : SelectQCbi<SETUGE, uimm16nonzero, Select_GPR_Using_CC_Uimm16NonZero>;
+} // let Predicates = [HasVendorXqcibi, IsRV32], AddedComplexity = 2
+
 let Predicates = [HasVendorXqciint, IsRV32] in
 def : Pat<(riscv_mileaveret_glue), (QC_C_MILEAVERET)>;
 
diff --git a/llvm/test/CodeGen/RISCV/xqcibi.ll b/llvm/test/CodeGen/RISCV/xqcibi.ll
new file mode 100644
index 0000000000000..242012b5ad462
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/xqcibi.ll
@@ -0,0 +1,359 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Test that we are able to generate the Xqcibi instructions
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s --check-prefixes=RV32I
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcibi -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s --check-prefixes=RV32IXQCIBI
+
+define i32 @beqimm(i32 %a) {
+; RV32I-LABEL: beqimm:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    li a1, -16
+; RV32I-NEXT:    beq a0, a1, .LBB0_2
+; RV32I-NEXT:  # %bb.1: # %f
+; RV32I-NEXT:    li a0, 0
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB0_2: # %t
+; RV32I-NEXT:    li a0, 1
+; RV32I-NEXT:    ret
+;
+; RV32IXQCIBI-LABEL: beqimm:
+; RV32IXQCIBI:       # %bb.0:
+; RV32IXQCIBI-NEXT:    qc.beqi a0, -16, .LBB0_2
+; RV32IXQCIBI-NEXT:  # %bb.1: # %f
+; RV32IXQCIBI-NEXT:    li a0, 0
+; RV32IXQCIBI-NEXT:    ret
+; RV32IXQCIBI-NEXT:  .LBB0_2: # %t
+; RV32IXQCIBI-NEXT:    li a0, 1
+; RV32IXQCIBI-NEXT:    ret
+  %1 = icmp eq i32 %a, -16
+  br i1 %1, label %t, label %f, !prof !0
+f:
+  ret i32 0
+t:
+  ret i32 1
+}
+
+define i32 @bneimm(i32 %a) {
+; RV32I-LABEL: bneimm:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    li a1, 15
+; RV32I-NEXT:    bne a0, a1, .LBB1_2
+; RV32I-NEXT:  # %bb.1: # %f
+; RV32I-NEXT:    li a0, 0
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB1_2: # %t
+; RV32I-NEXT:    li a0, 1
+; RV32I-NEXT:    ret
+;
+; RV32IXQCIBI-LABEL: bneimm:
+; RV32IXQCIBI:       # %bb.0:
+; RV32IXQCIBI-NEXT:    qc.bnei a0, 15, .LBB1_2
+; RV32IXQCIBI-NEXT:  # %bb.1: # %f
+; RV32IXQCIBI-NEXT:    li a0, 0
+; RV32IXQCIBI-NEXT:    ret
+; RV32IXQCIBI-NEXT:  .LBB1_2: # %t
+; RV32IXQCIBI-NEXT:    li a0, 1
+; RV32IXQCIBI-NEXT:    ret
+  %1 = icmp ne i32 %a, 15
+  br i1 %1, label %t, label %f, !prof !0
+f:
+  ret i32 0
+t:
+  ret i32 1
+}
+
+define i32 @bltimm(i32 %a) {
+; RV32I-LABEL: bltimm:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    li a1, 5
+; RV32I-NEXT:    blt a0, a1, .LBB2_2
+; RV32I-NEXT:  # %bb.1: # %f
+; RV32I-NEXT:    li a0, 0
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB2_2: # %t
+; RV32I-NEXT:    li a0, 1
+; RV32I-NEXT:    ret
+;
+; RV32IXQCIBI-LABEL: bltimm:
+; RV32IXQCIBI:       # %bb.0:
+; RV32IXQCIBI-NEXT:    qc.blti a0, 5, .LBB2_2
+; RV32IXQCIBI-NEXT:  # %bb.1: # %f
+; RV32IXQCIBI-NEXT:    li a0, 0
+; RV32IXQCIBI-NEXT:    ret
+; RV32IXQCIBI-NEXT:  .LBB2_2: # %t
+; RV32IXQCIBI-NEXT:    li a0, 1
+; RV32IXQCIBI-NEXT:    ret
+  %1 = icmp slt i32 %a, 5
+  br i1 %1, label %t, label %f, !prof !0
+f:
+  ret i32 0
+t:
+  ret i32 1
+}
+
+define i32 @bgeimm(i32 %a) {
+; RV32I-LABEL: bgeimm:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    li a1, -6
+; RV32I-NEXT:    blt a1, a0, .LBB3_2
+; RV32I-NEXT:  # %bb.1: # %f
+; RV32I-NEXT:    li a0, 0
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB3_2: # %t
+; RV32I-NEXT:    li a0, 1
+; RV32I-NEXT:    ret
+;
+; RV32IXQCIBI-LABEL: bgeimm:
+; RV32IXQCIBI:       # %bb.0:
+; RV32IXQCIBI-NEXT:    qc.bgei a0, -5, .LBB3_2
+; RV32IXQCIBI-NEXT:  # %bb.1: # %f
+; RV32IXQCIBI-NEXT:    li a0, 0
+; RV32IXQCIBI-NEXT:    ret
+; RV32IXQCIBI-NEXT:  .LBB3_2: # %t
+; RV32IXQCIBI-NEXT:    li a0, 1
+; RV32IXQCIBI-NEXT:    ret
+  %1 = icmp sge i32 %a, -5
+  br i1 %1, label %t, label %f, !prof !0
+f:
+  ret i32 0
+t:
+  ret i32 1
+}
+
+define i32 @bltuimm(i32 %a) {
+; RV32I-LABEL: bltuimm:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    li a1, 31
+; RV32I-NEXT:    bltu a0, a1, .LBB4_2
+; RV32I-NEXT:  # %bb.1: # %f
+; RV32I-NEXT:    li a0, 0
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB4_2: # %t
+; RV32I-NEXT:    li a0, 1
+; RV32I-NEXT:    ret
+;
+; RV32IXQCIBI-LABEL: bltuimm:
+; RV32IXQCIBI:       # %bb.0:
+; RV32IXQCIBI-NEXT:    qc.bltui a0, 31, .LBB4_2
+; RV32IXQCIBI-NEXT:  # %bb.1: # %f
+; RV32IXQCIBI-NEXT:    li a0, 0
+; RV32IXQCIBI-NEXT:    ret
+; RV32IXQCIBI-NEXT:  .LBB4_2: # %t
+; RV32IXQCIBI-NEXT:    li a0, 1
+; RV32IXQCIBI-NEXT:    ret
+  %1 = icmp ult i32 %a, 31
+  br i1 %1, label %t, label %f, !prof !0
+f:
+  ret i32 0
+t:
+  ret i32 1
+}
+
+define i32 @bgeuimm(i32 %a) {
+; RV32I-LABEL: bgeuimm:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    li a1, 9
+; RV32I-NEXT:    bltu a1, a0, .LBB5_2
+; RV32I-NEXT:  # %bb.1: # %f
+; RV32I-NEXT:    li a0, 0
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB5_2: # %t
+; RV32I-NEXT:    li a0, 1
+; RV32I-NEXT:    ret
+;
+; RV32IXQCIBI-LABEL: bgeuimm:
+; RV32IXQCIBI:       # %bb.0:
+; RV32IXQCIBI-NEXT:    qc.bgeui a0, 10, .LBB5_2
+; RV32IXQCIBI-NEXT:  # %bb.1: # %f
+; RV32IXQCIBI-NEXT:    li a0, 0
+; RV32IXQCIBI-NEXT:    ret
+; RV32IXQCIBI-NEXT:  .LBB5_2: # %t
+; RV32IXQCIBI-NEXT:    li a0, 1
+; RV32IXQCIBI-NEXT:    ret
+  %1 = icmp uge i32 %a, 10
+  br i1 %1, label %t, label %f, !prof !0
+f:
+  ret i32 0
+t:
+  ret i32 1
+}
+
+define i32 @beqimm16(i32 %a) {
+; RV32I-LABEL: beqimm16:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a1, 1048568
+; RV32I-NEXT:    beq a0, a1, .LBB6_2
+; RV32I-NEXT:  # %bb.1: # %f
+; RV32I-NEXT:    li a0, 0
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB6_2: # %t
+; RV32I-NEXT:    li a0, 1
+; RV32I-NEXT:    ret
+;
+; RV32IXQCIBI-LABEL: beqimm16:
+; RV32IXQCIBI:       # %bb.0:
+; RV32IXQCIBI-NEXT:    qc.e.beqi a0, -32768, .LBB6_2
+; RV32IXQCIBI-NEXT:  # %bb.1: # %f
+; RV32IXQCIBI-NEXT:    li a0, 0
+; RV32IXQCIBI-NEXT:    ret
+; RV32IXQCIBI-NEXT:  .LBB6_2: # %t
+; RV32IXQCIBI-NEXT:    li a0, 1
+; RV32IXQCIBI-NEXT:    ret
+  %1 = icmp eq i32 %a, -32768
+  br i1 %1, label %t, label %f, !prof !0
+f:
+  ret i32 0
+t:
+  ret i32 1
+}
+
+define i32 @bneimm16(i32 %a) {
+; RV32I-LABEL: bneimm16:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a1, 8
+; RV32I-NEXT:    addi a1, a1, -1
+; RV32I-NEXT:    bne a0, a1, .LBB7_2
+; RV32I-NEXT:  # %bb.1: # %f
+; RV32I-NEXT:    li a0, 0
+; RV32I-NEXT:    ret
+; RV32I-NEXT:  .LBB7_2: # %t
+; RV32I-NEXT:    li a0, 1
+; RV32I-NEXT:    ret
+;
+; RV32IXQCIBI-LABEL: bneimm16:
+; RV32IXQCIBI:       # %bb.0:
+; RV32IXQCIBI-NEXT:    qc.e.bnei a0, 32767, .LBB7_2
+; RV32IXQCIBI-NEXT:  # %bb.1: # %f
+; RV32IXQCIBI-NEXT:    li a0, 0
+; RV32IXQCIBI-NEXT:    ret
+; RV32IXQCIBI-NEXT:  .LBB7_2: # %t
+; RV32IXQCIBI-NEXT:    li a0, 1
+; RV32IXQCIBI-NEXT:    ret
+  %1 = icmp ne i32 %a, 32767
+  br i1 %1, label %t, label %f, !prof !0
+f:
+  ret i32 0
+t:
+  ret i32 1
+}
+
+define...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list