[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