[llvm] [RISCV] Add codegen patterns to support short forward branches with immediates (PR #185643)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 06:07:05 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: quic_hchandel (hchandel)

<details>
<summary>Changes</summary>

This is a follow-up to #<!-- -->182456. This PR adds support for short forward branches where branches are from Qualcomm uC `Xqcibi` extension.

---

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


16 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+6) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td (+40) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+22) 
- (modified) llvm/test/CodeGen/RISCV/features-info.ll (+1) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_eq.ll (+906) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_ne.ll (+906) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_sge.ll (+898) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_slt.ll (+898) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_uge.ll (+898) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_ult.ll (+898) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_48_eq.ll (+952) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_48_ne.ll (+952) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_48_sge.ll (+948) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_48_slt.ll (+948) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_48_uge.ll (+943) 
- (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_48_ult.ll (+943) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 99706970539ec..df5d1e19d3574 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -2001,6 +2001,12 @@ def TuneShortForwardBranchILoad
           [TuneShortForwardBranchIALU]>;
 def HasShortForwardBranchILoad : Predicate<"Subtarget->hasShortForwardBranchILoad()">;
 
+def TuneShortForwardBranchImm
+    : SubtargetFeature<"short-forward-branch-imm", "HasShortForwardBranchImm",
+                       "true", "Enable short forward branch optimization for branches with immediates",
+                       [TuneShortForwardBranchIALU]>;
+def HasShortForwardBranchImm : Predicate<"Subtarget->hasShortForwardBranchImm()">;
+
 // Some subtargets require a S2V transfer buffer to move scalars into vectors.
 // FIXME: Forming .vx/.vf/.wx/.wf can reduce register pressure.
 def TuneNoSinkSplatOperands
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
index c02aa06c66c64..3838c1c4b1095 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
@@ -29,6 +29,46 @@ def CCtoRISCVBCC : SDNodeXForm<cond, [{
   return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
 }]>;
 
+// cond -> bcc_opcode (QC_E_BccI)
+def CCtoQC_E_BccI : SDNodeXForm<cond, [{
+  ISD::CondCode CC = N->get();
+  RISCVCC::CondCode RvCC = getRISCVCCForIntCC(CC);
+  RvCC = RISCVCC::getInverseBranchCondition(RvCC);
+  unsigned SelectOpc;
+  switch (RvCC) {
+  case RISCVCC::COND_LTU:
+  case RISCVCC::COND_GEU:
+    SelectOpc = RISCV::Select_GPRNoX0_Using_CC_UImm16NonZero_QC;
+    break;
+  default:
+    // EQ/NE/LT/GE treated as signed condition codes
+    SelectOpc = RISCV::Select_GPRNoX0_Using_CC_SImm16NonZero_QC;
+    break;
+  }
+  unsigned BccOpcode = RISCVCC::getBrCond(RvCC, SelectOpc);
+  return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
+}]>;
+
+// cond -> bcc_opcode (QC_BeqI)
+def CCtoQC_BccI : SDNodeXForm<cond, [{
+  ISD::CondCode CC = N->get();
+  RISCVCC::CondCode RvCC = getRISCVCCForIntCC(CC);
+  RvCC = RISCVCC::getInverseBranchCondition(RvCC);
+  unsigned SelectOpc;
+  switch (RvCC) {
+  case RISCVCC::COND_LTU:
+  case RISCVCC::COND_GEU:
+    SelectOpc = RISCV::Select_GPRNoX0_Using_CC_UImm5NonZero_QC;
+    break;
+  default:
+    // EQ/NE/LT/GE treated as signed condition codes
+    SelectOpc = RISCV::Select_GPRNoX0_Using_CC_SImm5NonZero_QC;
+    break;
+  }
+  unsigned BccOpcode = RISCVCC::getBrCond(RvCC, SelectOpc);
+  return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
+}]>;
+
 // For each of the short forward branch pseudos, corresponding code for
 // getting correct size of the pseduo is needed in getInstSizeInBytes.
 let Predicates = [HasShortForwardBranchIALU], isSelect = 1,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index c2051973be186..912122399de3e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1500,6 +1500,12 @@ class SelectQCbi<CondCode Cond, DAGOperand InTyImm, Pseudo OpNode >
           (OpNode GPRNoX0:$lhs, InTyImm:$Constant, (CCtoRISCVCC $cc),
                   GPRNoX0:$truev, GPRNoX0:$falsev)>;
 
+class SelectQCbiSFB<CondCode Cond, DAGOperand InTyImm, SDNodeXForm xform>
+    : Pat<(riscv_selectcc (i32 GPRNoX0:$lhs), InTyImm:$Constant, Cond:$cc,
+                          (i32 GPR:$truev), GPR:$falsev),
+          (PseudoCCMOVGPR GPR:$falsev, GPR:$truev, (xform $cc), GPRNoX0:$lhs,
+                          InTyImm:$Constant)>;
+
 let Predicates = [HasVendorXqciac, IsRV32] in {
 def : Pat<(i32 (add GPRNoX0:$rd, (mul GPRNoX0:$rs1, simm12_lo:$imm12))),
           (QC_MULIADD GPRNoX0:$rd, GPRNoX0:$rs1, simm12_lo:$imm12)>;
@@ -1563,6 +1569,22 @@ def : PatGprNoX0GprNoX0<ushlsat, QC_SHLUSAT>;
 def : PatGprNoX0GprNoX0<sshlsat, QC_SHLSAT>;
 } // Predicates = [HasVendorXqcia, IsRV32]
 
+let Predicates = [HasShortForwardBranchImm, HasVendorXqcibi, IsRV32] in {
+def : SelectQCbiSFB<SETEQ, simm5nonzero, CCtoQC_BccI>;
+def : SelectQCbiSFB<SETNE, simm5nonzero, CCtoQC_BccI>;
+def : SelectQCbiSFB<SETGE, simm5nonzero, CCtoQC_BccI>;
+def : SelectQCbiSFB<SETLT, simm5nonzero, CCtoQC_BccI>;
+def : SelectQCbiSFB<SETULT, uimm5nonzero, CCtoQC_BccI>;
+def : SelectQCbiSFB<SETUGE, uimm5nonzero, CCtoQC_BccI>;
+
+def : SelectQCbiSFB<SETEQ, simm16nonzero, CCtoQC_E_BccI>;
+def : SelectQCbiSFB<SETGE, simm16nonzero, CCtoQC_E_BccI>;
+def : SelectQCbiSFB<SETLT, simm16nonzero, CCtoQC_E_BccI>;
+def : SelectQCbiSFB<SETNE, simm16nonzero, CCtoQC_E_BccI>;
+def : SelectQCbiSFB<SETUGE, uimm16nonzero, CCtoQC_E_BccI>;
+def : SelectQCbiSFB<SETUGE, uimm16nonzero, CCtoQC_E_BccI>;
+}
+
 /// Branches
 
 let Predicates = [HasVendorXqcibi, IsRV32] in {
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 05c932aa359e2..f1a46b1be4dd8 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -130,6 +130,7 @@
 ; CHECK-NEXT:   short-forward-branch-ialu        - Enable short forward branch optimization for RVI base instructions.
 ; CHECK-NEXT:   short-forward-branch-iload       - Enable short forward branch optimization for load instructions.
 ; CHECK-NEXT:   short-forward-branch-iminmax     - Enable short forward branch optimization for MIN,MAX instructions in Zbb.
+; CHECK-NEXT:   short-forward-branch-imm         - Enable short forward branch optimization for branches with immediates.
 ; CHECK-NEXT:   short-forward-branch-imul        - Enable short forward branch optimization for MUL instruction.
 ; CHECK-NEXT:   shtvala                          - 'Shtvala' (htval provides all needed values).
 ; CHECK-NEXT:   shvsatpa                         - 'Shvsatpa' (vsatp supports all modes supported by satp).
diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_eq.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_eq.ll
new file mode 100644
index 0000000000000..c3cae128b3754
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/short-forward-branch-opt-with-branch-with-immediates_32_eq.ll
@@ -0,0 +1,906 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -verify-machineinstrs -mtriple=riscv32 | FileCheck %s --check-prefixes=RV32I
+; RUN: llc < %s -verify-machineinstrs -mtriple=riscv32 -mattr=+xqci,+short-forward-branch-ialu,+short-forward-branch-imul,+short-forward-branch-iload,+short-forward-branch-imm,+m | \
+; RUN:   FileCheck %s --check-prefixes=RV32I-SFB-WITH-IMM
+
+define i32 @branch_with_immSFB_mv(i32 %a, i32 %c, i32 %d) {
+; RV32I-LABEL: branch_with_immSFB_mv:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a3, 2
+; RV32I-NEXT:    beq a2, a3, .LBB0_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a1
+; RV32I-NEXT:  .LBB0_2: # %entry
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_mv:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.beqi a2, 2, .LBB0_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a1
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB0_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %sel = select i1 %x, i32 %a, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_mv_zerofalsev(i32 %a, i32 %c, i32 %d) {
+; RV32I-LABEL: branch_with_immSFB_mv_zerofalsev:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    addi a2, a2, -2
+; RV32I-NEXT:    snez a1, a2
+; RV32I-NEXT:    addi a1, a1, -1
+; RV32I-NEXT:    and a0, a1, a0
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_mv_zerofalsev:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.selectieqi a2, 2, a0, 0
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %sel = select i1 %x, i32 %a, i32 0
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_mv_zerofalsev_swapped(i32 %a, i32 %c, i32 %d) {
+; RV32I-LABEL: branch_with_immSFB_mv_zerofalsev_swapped:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    addi a2, a2, -2
+; RV32I-NEXT:    seqz a1, a2
+; RV32I-NEXT:    addi a1, a1, -1
+; RV32I-NEXT:    and a0, a1, a0
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_mv_zerofalsev_swapped:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.selectinei a2, 2, a0, 0
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %sel = select i1 %x, i32 0, i32 %a
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_mv_minusOnefalsev(i32 %a, i32 %c, i32 %d) {
+; RV32I-LABEL: branch_with_immSFB_mv_minusOnefalsev:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    addi a2, a2, -2
+; RV32I-NEXT:    seqz a1, a2
+; RV32I-NEXT:    addi a1, a1, -1
+; RV32I-NEXT:    or a0, a1, a0
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_mv_minusOnefalsev:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.selectieqi a2, 2, a0, -1
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %sel = select i1 %x, i32 %a, i32 -1
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_mv_minusOnefalsev_swapped(i32 %a, i32 %c, i32 %d) {
+; RV32I-LABEL: branch_with_immSFB_mv_minusOnefalsev_swapped:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    addi a2, a2, -2
+; RV32I-NEXT:    snez a1, a2
+; RV32I-NEXT:    addi a1, a1, -1
+; RV32I-NEXT:    or a0, a1, a0
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_mv_minusOnefalsev_swapped:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.selectinei a2, 2, a0, -1
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %sel = select i1 %x, i32 -1, i32 %a
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_add(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_add:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a4, 2
+; RV32I-NEXT:    bne a3, a4, .LBB5_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    add a2, a0, a1
+; RV32I-NEXT:  .LBB5_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_add:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB5_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    add a2, a0, a1
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB5_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %addi = add i32 %a, %b
+  %sel = select i1 %x, i32 %addi, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_sub(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_sub:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a4, 2
+; RV32I-NEXT:    bne a3, a4, .LBB6_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    sub a2, a0, a1
+; RV32I-NEXT:  .LBB6_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_sub:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB6_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    sub a2, a0, a1
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB6_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %subi = sub i32 %a, %b
+  %sel = select i1 %x, i32 %subi, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_shl(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_shl:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a4, 2
+; RV32I-NEXT:    bne a3, a4, .LBB7_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    sll a2, a0, a1
+; RV32I-NEXT:  .LBB7_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_shl:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB7_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    sll a2, a0, a1
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB7_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %shli = shl i32 %a, %b
+  %sel = select i1 %x, i32 %shli, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_lshr(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_lshr:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a4, 2
+; RV32I-NEXT:    bne a3, a4, .LBB8_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    srl a2, a0, a1
+; RV32I-NEXT:  .LBB8_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_lshr:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB8_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    srl a2, a0, a1
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB8_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %lshri = lshr i32 %a, %b
+  %sel = select i1 %x, i32 %lshri, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_ashr(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_ashr:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a4, 2
+; RV32I-NEXT:    bne a3, a4, .LBB9_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    sra a2, a0, a1
+; RV32I-NEXT:  .LBB9_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_ashr:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB9_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    sra a2, a0, a1
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB9_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %ashri = ashr i32 %a, %b
+  %sel = select i1 %x, i32 %ashri, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_xor(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_xor:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a4, 2
+; RV32I-NEXT:    bne a3, a4, .LBB10_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    xor a2, a0, a1
+; RV32I-NEXT:  .LBB10_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_xor:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB10_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    xor a2, a0, a1
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB10_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %xori = xor i32 %a, %b
+  %sel = select i1 %x, i32 %xori, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_and(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_and:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a4, 2
+; RV32I-NEXT:    bne a3, a4, .LBB11_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    and a2, a0, a1
+; RV32I-NEXT:  .LBB11_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_and:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB11_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    and a2, a0, a1
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB11_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %andi = and i32 %a, %b
+  %sel = select i1 %x, i32 %andi, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_or(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_or:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a4, 2
+; RV32I-NEXT:    bne a3, a4, .LBB12_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    or a2, a0, a1
+; RV32I-NEXT:  .LBB12_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_or:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB12_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    or a2, a0, a1
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB12_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %ori = or i32 %a, %b
+  %sel = select i1 %x, i32 %ori, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_addi(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_addi:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a1, 2
+; RV32I-NEXT:    bne a3, a1, .LBB13_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    addi a2, a0, 11
+; RV32I-NEXT:  .LBB13_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_addi:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB13_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    addi a2, a0, 11
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB13_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %addi = add i32 %a, 11
+  %sel = select i1 %x, i32 %addi, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_xori(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_xori:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a1, 2
+; RV32I-NEXT:    bne a3, a1, .LBB14_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    xori a2, a0, 11
+; RV32I-NEXT:  .LBB14_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_xori:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB14_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    xori a2, a0, 11
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB14_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %xori = xor i32 %a, 11
+  %sel = select i1 %x, i32 %xori, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_shli(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_shli:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a1, 2
+; RV32I-NEXT:    bne a3, a1, .LBB15_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    slli a2, a0, 11
+; RV32I-NEXT:  .LBB15_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_shli:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB15_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    slli a2, a0, 11
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB15_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %shli = shl i32 %a, 11
+  %sel = select i1 %x, i32 %shli, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_immSFB_lshri(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
+; RV32I-LABEL: branch_with_immSFB_lshri:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    li a1, 2
+; RV32I-NEXT:    bne a3, a1, .LBB16_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    srli a2, a0, 11
+; RV32I-NEXT:  .LBB16_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-WITH-IMM-LABEL: branch_with_immSFB_lshri:
+; RV32I-SFB-WITH-IMM:       # %bb.0: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    qc.bnei a3, 2, .LBB16_2
+; RV32I-SFB-WITH-IMM-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    srli a2, a0, 11
+; RV32I-SFB-WITH-IMM-NEXT:  .LBB16_2: # %entry
+; RV32I-SFB-WITH-IMM-NEXT:    mv a0, a2
+; RV32I-SFB-WITH-IMM-NEXT:    ret
+entry:
+  %x = icmp eq i32 %d, 2
+  %lshri = lshr i32 %a, 11
+  %sel = select i1 %x, i32 %lshri, i32 %c
+  ret i32 %sel
+}
+
+define i32 @branch_with_im...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list