[llvm] 42ab473 - [RISCV] Xqci with Short Forward Branches (#161407)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 1 10:00:44 PDT 2025


Author: Sam Elliott
Date: 2025-10-01T10:00:40-07:00
New Revision: 42ab473f518c5f180455c674cbaba70a0b2634b7

URL: https://github.com/llvm/llvm-project/commit/42ab473f518c5f180455c674cbaba70a0b2634b7
DIFF: https://github.com/llvm/llvm-project/commit/42ab473f518c5f180455c674cbaba70a0b2634b7.diff

LOG: [RISCV] Xqci with Short Forward Branches (#161407)

This change implements support for the combination of Xqci and the Short
Forward Branch optimisation.

In particular, we want to prioritise `Branch+ALU` (short forward
branches) over the equivalent `ALU+CMov`, when the compared values are
both registers, and the selected values come from registers (as this is
what `PseudoCCMOVGPR` supports).

However, when expanding `PseudoCCMOVGPR` (i.e., `Branch+MV`), we instead
want to expand it to a conditional move (for code size reasons), so I
have added `RISCVExpandPseudo::expandCCOpToCMov` to try to do so. This
mostly works, except if `PseudoCCMOVGPR` is comparing against zero and
gets commuted - as can be seen in one example in `foo` in
`select-cc.ll`.

This change:
- updates the attributes used for the XQCI RUN lines for the select
tests.
- modifies the CodeGen patterns and predicates to prioritise selecting
the SFB Pseudo.
- adds CodeGen patterns for MVLTI/MVLTUI/MVGEI/MVGEUI with imm=zero, to
prioritise over the equivalent `Select_GPR_Using_CC_GPR` patterns for
rhs=X0.
- adds a hook to attempt to turn the predicated-mov Pseudo back into a
Conditional Move from Xqcicm (which matches the pseudo in terms of tied
register operands).

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
    llvm/test/CodeGen/RISCV/cmov-branch-opt.ll
    llvm/test/CodeGen/RISCV/select-bare.ll
    llvm/test/CodeGen/RISCV/select-cc.ll
    llvm/test/CodeGen/RISCV/select-cond.ll
    llvm/test/CodeGen/RISCV/select-const.ll
    llvm/test/CodeGen/RISCV/select.ll
    llvm/test/CodeGen/RISCV/xqcicli.ll
    llvm/test/CodeGen/RISCV/xqcicm.ll
    llvm/test/CodeGen/RISCV/xqcics.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index d4d9e5430d390..410561855e181 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -46,6 +46,8 @@ class RISCVExpandPseudo : public MachineFunctionPass {
                 MachineBasicBlock::iterator &NextMBBI);
   bool expandCCOp(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
                   MachineBasicBlock::iterator &NextMBBI);
+  bool expandCCOpToCMov(MachineBasicBlock &MBB,
+                        MachineBasicBlock::iterator MBBI);
   bool expandVMSET_VMCLR(MachineBasicBlock &MBB,
                          MachineBasicBlock::iterator MBBI, unsigned Opcode);
   bool expandMV_FPR16INX(MachineBasicBlock &MBB,
@@ -178,6 +180,9 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
 bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator MBBI,
                                    MachineBasicBlock::iterator &NextMBBI) {
+  // First try expanding to a Conditional Move rather than a branch+mv
+  if (expandCCOpToCMov(MBB, MBBI))
+    return true;
 
   MachineFunction *MF = MBB.getParent();
   MachineInstr &MI = *MBBI;
@@ -277,6 +282,86 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
   return true;
 }
 
+bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
+                                         MachineBasicBlock::iterator MBBI) {
+  MachineInstr &MI = *MBBI;
+  DebugLoc DL = MI.getDebugLoc();
+
+  if (MI.getOpcode() != RISCV::PseudoCCMOVGPR &&
+      MI.getOpcode() != RISCV::PseudoCCMOVGPRNoX0)
+    return false;
+
+  if (!STI->hasVendorXqcicm())
+    return false;
+
+  // FIXME: Would be wonderful to support LHS=X0, but not very easy.
+  if (MI.getOperand(1).getReg() == RISCV::X0 ||
+      MI.getOperand(4).getReg() == RISCV::X0 ||
+      MI.getOperand(5).getReg() == RISCV::X0)
+    return false;
+
+  auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
+
+  unsigned CMovOpcode, CMovIOpcode;
+  switch (CC) {
+  default:
+    llvm_unreachable("Unhandled CC");
+  case RISCVCC::COND_EQ:
+    CMovOpcode = RISCV::QC_MVEQ;
+    CMovIOpcode = RISCV::QC_MVEQI;
+    break;
+  case RISCVCC::COND_NE:
+    CMovOpcode = RISCV::QC_MVNE;
+    CMovIOpcode = RISCV::QC_MVNEI;
+    break;
+  case RISCVCC::COND_LT:
+    CMovOpcode = RISCV::QC_MVLT;
+    CMovIOpcode = RISCV::QC_MVLTI;
+    break;
+  case RISCVCC::COND_GE:
+    CMovOpcode = RISCV::QC_MVGE;
+    CMovIOpcode = RISCV::QC_MVGEI;
+    break;
+  case RISCVCC::COND_LTU:
+    CMovOpcode = RISCV::QC_MVLTU;
+    CMovIOpcode = RISCV::QC_MVLTUI;
+    break;
+  case RISCVCC::COND_GEU:
+    CMovOpcode = RISCV::QC_MVGEU;
+    CMovIOpcode = RISCV::QC_MVGEUI;
+    break;
+  }
+
+  if (MI.getOperand(2).getReg() == RISCV::X0) {
+    // $dst = PseudoCCMOVGPR $lhs, X0, $cc, $falsev (=$dst), $truev
+    // $dst = PseudoCCMOVGPRNoX0 $lhs, X0, $cc, $falsev (=$dst), $truev
+    // =>
+    // $dst = QC_MVccI $falsev (=$dst), $lhs, 0, $truev
+    BuildMI(MBB, MBBI, DL, TII->get(CMovIOpcode))
+        .addDef(MI.getOperand(0).getReg())
+        .addReg(MI.getOperand(4).getReg())
+        .addReg(MI.getOperand(1).getReg())
+        .addImm(0)
+        .addReg(MI.getOperand(5).getReg());
+
+    MI.eraseFromParent();
+    return true;
+  }
+
+  // $dst = PseudoCCMOVGPR $lhs, $rhs, $cc, $falsev (=$dst), $truev
+  // $dst = PseudoCCMOVGPRNoX0 $lhs, $rhs, $cc, $falsev (=$dst), $truev
+  // =>
+  // $dst = QC_MVcc $falsev (=$dst), $lhs, $rhs, $truev
+  BuildMI(MBB, MBBI, DL, TII->get(CMovOpcode))
+      .addDef(MI.getOperand(0).getReg())
+      .addReg(MI.getOperand(4).getReg())
+      .addReg(MI.getOperand(1).getReg())
+      .addReg(MI.getOperand(2).getReg())
+      .addReg(MI.getOperand(5).getReg());
+  MI.eraseFromParent();
+  return true;
+}
+
 bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock &MBB,
                                           MachineBasicBlock::iterator MBBI,
                                           unsigned Opcode) {

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 540786851e2d5..efdbd1298aec6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -1350,6 +1350,10 @@ class QCIMVCCIPat<CondCode Cond, QCIMVCCI Inst, DAGOperand InTyImm>
     : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), InTyImm:$imm, Cond, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
           (Inst GPRNoX0:$rd, GPRNoX0:$rs1, InTyImm:$imm, GPRNoX0:$rs3)>;
 
+class QCIMVCCIZeroPat<CondCode Cond, QCIMVCCI Inst>
+    : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 0), Cond, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
+          (Inst GPRNoX0:$rd, GPRNoX0:$rs1, 0, GPRNoX0:$rs3)>;
+
 class QCISELECTCCIPat<CondCode Cond, QCISELECTCCI Inst>
     : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rd), simm5:$imm, Cond, (i32 GPRNoX0:$rs2), (i32 GPRNoX0:$rs3))),
           (Inst GPRNoX0:$rd, simm5:$imm, GPRNoX0:$rs2, GPRNoX0:$rs3)>;
@@ -1538,14 +1542,7 @@ def: Pat<(i32 (ctlz (not (i32 GPR:$rs1)))), (QC_CLO GPR:$rs1)>;
 let Predicates = [HasVendorXqciint, IsRV32] in
 def : Pat<(riscv_mileaveret_glue), (QC_C_MILEAVERET)>;
 
-let Predicates = [HasVendorXqcicm, IsRV32] in {
-// (SELECT X, Y, Z) is canonicalised to `(riscv_selectcc x, 0, NE, y, z)`.
-// This exists to prioritise over the `Select_GPR_Using_CC_GPR` pattern.
-def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 0), SETNE, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
-          (QC_MVNEI GPRNoX0:$rd, GPRNoX0:$rs1, 0, GPRNoX0:$rs3)>;
-def : Pat<(i32 (riscv_selectcc (i32 GPRNoX0:$rs1), (i32 0), SETEQ, (i32 GPRNoX0:$rs3), (i32 GPRNoX0:$rd))),
-          (QC_MVEQI GPRNoX0:$rd, GPRNoX0:$rs1, 0, GPRNoX0:$rs3)>;
-
+let Predicates = [HasVendorXqcicm, NoShortForwardBranchOpt, IsRV32] in {
 def : QCIMVCCPat<SETEQ,  QC_MVEQ>;
 def : QCIMVCCPat<SETNE,  QC_MVNE>;
 def : QCIMVCCPat<SETLT,  QC_MVLT>;
@@ -1553,12 +1550,24 @@ def : QCIMVCCPat<SETULT, QC_MVLTU>;
 def : QCIMVCCPat<SETGE,  QC_MVGE>;
 def : QCIMVCCPat<SETUGE, QC_MVGEU>;
 
-def : QCIMVCCIPat<SETEQ,  QC_MVEQI,  simm5>;
-def : QCIMVCCIPat<SETNE,  QC_MVNEI,  simm5>;
-def : QCIMVCCIPat<SETLT,  QC_MVLTI,  simm5>;
-def : QCIMVCCIPat<SETULT, QC_MVLTUI, uimm5>;
-def : QCIMVCCIPat<SETGE,  QC_MVGEI,  simm5>;
-def : QCIMVCCIPat<SETUGE, QC_MVGEUI, uimm5>;
+// These exist to prioritise over the `Select_GPR_Using_CC_GPR` pattern for X0.
+def : QCIMVCCIZeroPat<SETEQ,  QC_MVEQI>;
+def : QCIMVCCIZeroPat<SETNE,  QC_MVNEI>;
+def : QCIMVCCIZeroPat<SETLT,  QC_MVLTI>;
+def : QCIMVCCIZeroPat<SETULT, QC_MVLTUI>;
+def : QCIMVCCIZeroPat<SETGE,  QC_MVGEI>;
+def : QCIMVCCIZeroPat<SETUGE, QC_MVGEUI>;
+}
+
+let Predicates = [HasVendorXqcicm, IsRV32] in {
+// These all use *imm5nonzero because we want to use PseudoCCMOVGPR with X0 when SFB is enabled.
+// When SFB is not enabled, the `QCIMVCCIZeroPat`s above will be used if RHS=0.
+def : QCIMVCCIPat<SETEQ,  QC_MVEQI,  simm5nonzero>;
+def : QCIMVCCIPat<SETNE,  QC_MVNEI,  simm5nonzero>;
+def : QCIMVCCIPat<SETLT,  QC_MVLTI,  simm5nonzero>;
+def : QCIMVCCIPat<SETULT, QC_MVLTUI, uimm5nonzero>;
+def : QCIMVCCIPat<SETGE,  QC_MVGEI,  simm5nonzero>;
+def : QCIMVCCIPat<SETUGE, QC_MVGEUI, uimm5nonzero>;
 }
 
 let Predicates = [HasVendorXqcicli, IsRV32] in {

diff  --git a/llvm/test/CodeGen/RISCV/cmov-branch-opt.ll b/llvm/test/CodeGen/RISCV/cmov-branch-opt.ll
index f8b1d505f4e81..edec1d0b649ce 100644
--- a/llvm/test/CodeGen/RISCV/cmov-branch-opt.ll
+++ b/llvm/test/CodeGen/RISCV/cmov-branch-opt.ll
@@ -11,6 +11,8 @@
 ; RUN:   | FileCheck -check-prefixes=SHORT_FORWARD,SFB-NOZICOND,SFB-NOZICOND-C %s
 ; RUN: llc -mtriple=riscv64 -mattr=+short-forward-branch-opt,+zicond -verify-machineinstrs < %s \
 ; RUN:   | FileCheck -check-prefixes=SHORT_FORWARD,SFB-ZICOND %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s --check-prefixes=RV32IXQCI
 
 ; The conditional move optimization in sifive-p450 requires that only a
 ; single c.mv instruction appears in the branch shadow.
@@ -42,6 +44,14 @@ define signext i32 @test1(i32 signext %x, i32 signext %y, i32 signext %z) {
 ; SHORT_FORWARD-NEXT:    xor a0, a0, a1
 ; SHORT_FORWARD-NEXT:  .LBB0_2:
 ; SHORT_FORWARD-NEXT:    ret
+;
+; RV32IXQCI-LABEL: test1:
+; RV32IXQCI:       # %bb.0:
+; RV32IXQCI-NEXT:    bnez a2, .LBB0_2
+; RV32IXQCI-NEXT:  # %bb.1:
+; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB0_2:
+; RV32IXQCI-NEXT:    ret
   %c = icmp eq i32 %z, 0
   %a = xor i32 %x, %y
   %b = select i1 %c, i32 %a, i32 %x
@@ -73,6 +83,14 @@ define signext i32 @test2(i32 signext %x, i32 signext %y, i32 signext %z) {
 ; SHORT_FORWARD-NEXT:    xor a0, a0, a1
 ; SHORT_FORWARD-NEXT:  .LBB1_2:
 ; SHORT_FORWARD-NEXT:    ret
+;
+; RV32IXQCI-LABEL: test2:
+; RV32IXQCI:       # %bb.0:
+; RV32IXQCI-NEXT:    beqz a2, .LBB1_2
+; RV32IXQCI-NEXT:  # %bb.1:
+; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB1_2:
+; RV32IXQCI-NEXT:    ret
   %c = icmp eq i32 %z, 0
   %a = xor i32 %x, %y
   %b = select i1 %c, i32 %x, i32 %a
@@ -120,6 +138,19 @@ define signext i32 @test3(i32 signext %v, i32 signext %w, i32 signext %x, i32 si
 ; SHORT_FORWARD-NEXT:  .LBB2_4:
 ; SHORT_FORWARD-NEXT:    addw a0, a0, a2
 ; SHORT_FORWARD-NEXT:    ret
+;
+; RV32IXQCI-LABEL: test3:
+; RV32IXQCI:       # %bb.0:
+; RV32IXQCI-NEXT:    beqz a4, .LBB2_2
+; RV32IXQCI-NEXT:  # %bb.1:
+; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB2_2:
+; RV32IXQCI-NEXT:    beqz a4, .LBB2_4
+; RV32IXQCI-NEXT:  # %bb.3:
+; RV32IXQCI-NEXT:    xor a2, a2, a3
+; RV32IXQCI-NEXT:  .LBB2_4:
+; RV32IXQCI-NEXT:    add a0, a0, a2
+; RV32IXQCI-NEXT:    ret
   %c = icmp eq i32 %z, 0
   %a = xor i32 %v, %w
   %b = select i1 %c, i32 %v, i32 %a
@@ -167,6 +198,12 @@ define signext i32 @test4(i32 signext %x, i32 signext %y, i32 signext %z) {
 ; SFB-ZICOND-NEXT:    li a0, 3
 ; SFB-ZICOND-NEXT:    czero.nez a0, a0, a2
 ; SFB-ZICOND-NEXT:    ret
+;
+; RV32IXQCI-LABEL: test4:
+; RV32IXQCI:       # %bb.0:
+; RV32IXQCI-NEXT:    li a0, 0
+; RV32IXQCI-NEXT:    qc.lieqi a0, a2, 0, 3
+; RV32IXQCI-NEXT:    ret
   %c = icmp eq i32 %z, 0
   %a = select i1 %c, i32 3, i32 0
   ret i32 %a
@@ -199,6 +236,15 @@ define i16 @select_xor_1(i16 %A, i8 %cond) {
 ; SHORT_FORWARD-NEXT:    xori a0, a0, 43
 ; SHORT_FORWARD-NEXT:  .LBB4_2: # %entry
 ; SHORT_FORWARD-NEXT:    ret
+;
+; RV32IXQCI-LABEL: select_xor_1:
+; RV32IXQCI:       # %bb.0: # %entry
+; RV32IXQCI-NEXT:    andi a1, a1, 1
+; RV32IXQCI-NEXT:    beqz a1, .LBB4_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    xori a0, a0, 43
+; RV32IXQCI-NEXT:  .LBB4_2: # %entry
+; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
  %cmp10 = icmp eq i8 %and, 0
@@ -236,6 +282,15 @@ define i16 @select_xor_1b(i16 %A, i8 %cond) {
 ; SHORT_FORWARD-NEXT:    xori a0, a0, 43
 ; SHORT_FORWARD-NEXT:  .LBB5_2: # %entry
 ; SHORT_FORWARD-NEXT:    ret
+;
+; RV32IXQCI-LABEL: select_xor_1b:
+; RV32IXQCI:       # %bb.0: # %entry
+; RV32IXQCI-NEXT:    andi a1, a1, 1
+; RV32IXQCI-NEXT:    beqz a1, .LBB5_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    xori a0, a0, 43
+; RV32IXQCI-NEXT:  .LBB5_2: # %entry
+; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
  %cmp10 = icmp ne i8 %and, 1
@@ -289,6 +344,15 @@ define i32 @select_xor_2(i32 %A, i32 %B, i8 %cond) {
 ; SFB-ZICOND-NEXT:    xor a0, a1, a0
 ; SFB-ZICOND-NEXT:  .LBB6_2: # %entry
 ; SFB-ZICOND-NEXT:    ret
+;
+; RV32IXQCI-LABEL: select_xor_2:
+; RV32IXQCI:       # %bb.0: # %entry
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB6_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB6_2: # %entry
+; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
  %cmp10 = icmp eq i8 %and, 0
@@ -344,6 +408,15 @@ define i32 @select_xor_2b(i32 %A, i32 %B, i8 %cond) {
 ; SFB-ZICOND-NEXT:    xor a0, a1, a0
 ; SFB-ZICOND-NEXT:  .LBB7_2: # %entry
 ; SFB-ZICOND-NEXT:    ret
+;
+; RV32IXQCI-LABEL: select_xor_2b:
+; RV32IXQCI:       # %bb.0: # %entry
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB7_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB7_2: # %entry
+; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
  %cmp10 = icmp ne i8 %and, 1
@@ -397,6 +470,15 @@ define i32 @select_or(i32 %A, i32 %B, i8 %cond) {
 ; SFB-ZICOND-NEXT:    or a0, a1, a0
 ; SFB-ZICOND-NEXT:  .LBB8_2: # %entry
 ; SFB-ZICOND-NEXT:    ret
+;
+; RV32IXQCI-LABEL: select_or:
+; RV32IXQCI:       # %bb.0: # %entry
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB8_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB8_2: # %entry
+; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
  %cmp10 = icmp eq i8 %and, 0
@@ -452,6 +534,15 @@ define i32 @select_or_b(i32 %A, i32 %B, i8 %cond) {
 ; SFB-ZICOND-NEXT:    or a0, a1, a0
 ; SFB-ZICOND-NEXT:  .LBB9_2: # %entry
 ; SFB-ZICOND-NEXT:    ret
+;
+; RV32IXQCI-LABEL: select_or_b:
+; RV32IXQCI:       # %bb.0: # %entry
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB9_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB9_2: # %entry
+; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
  %cmp10 = icmp ne i8 %and, 1
@@ -505,6 +596,15 @@ define i32 @select_or_1(i32 %A, i32 %B, i32 %cond) {
 ; SFB-ZICOND-NEXT:    or a0, a1, a0
 ; SFB-ZICOND-NEXT:  .LBB10_2: # %entry
 ; SFB-ZICOND-NEXT:    ret
+;
+; RV32IXQCI-LABEL: select_or_1:
+; RV32IXQCI:       # %bb.0: # %entry
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB10_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB10_2: # %entry
+; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i32 %cond, 1
  %cmp10 = icmp eq i32 %and, 0
@@ -560,6 +660,15 @@ define i32 @select_or_1b(i32 %A, i32 %B, i32 %cond) {
 ; SFB-ZICOND-NEXT:    or a0, a1, a0
 ; SFB-ZICOND-NEXT:  .LBB11_2: # %entry
 ; SFB-ZICOND-NEXT:    ret
+;
+; RV32IXQCI-LABEL: select_or_1b:
+; RV32IXQCI:       # %bb.0: # %entry
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB11_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB11_2: # %entry
+; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i32 %cond, 1
  %cmp10 = icmp ne i32 %and, 1

diff  --git a/llvm/test/CodeGen/RISCV/select-bare.ll b/llvm/test/CodeGen/RISCV/select-bare.ll
index 44028a7651b95..550eb94724ff2 100644
--- a/llvm/test/CodeGen/RISCV/select-bare.ll
+++ b/llvm/test/CodeGen/RISCV/select-bare.ll
@@ -3,7 +3,7 @@
 ; RUN:   | FileCheck %s -check-prefix=RV32I
 ; RUN: llc -mtriple=riscv64 -mattr=+xmipscmov -verify-machineinstrs < %s \
 ; RUN:   | FileCheck -check-prefix=RV64I-CCMOV %s
-; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCI
 
 define i32 @bare_select(i1 %a, i32 %b, i32 %c) nounwind {

diff  --git a/llvm/test/CodeGen/RISCV/select-cc.ll b/llvm/test/CodeGen/RISCV/select-cc.ll
index b57f625cb867f..95f5a9d0925de 100644
--- a/llvm/test/CodeGen/RISCV/select-cc.ll
+++ b/llvm/test/CodeGen/RISCV/select-cc.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -mtriple=riscv32 -disable-block-placement -verify-machineinstrs < %s \
 ; RUN:   | FileCheck -check-prefixes=RV32I %s
-; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCI
 ; RUN: llc -mtriple=riscv64 -disable-block-placement -verify-machineinstrs < %s \
 ; RUN:   | FileCheck -check-prefixes=RV64I %s
@@ -88,39 +88,38 @@ define signext i32 @foo(i32 signext %a, ptr %b) nounwind {
 ; RV32IXQCI-LABEL: foo:
 ; RV32IXQCI:       # %bb.0:
 ; RV32IXQCI-NEXT:    lw a2, 0(a1)
-; RV32IXQCI-NEXT:    lw a4, 0(a1)
-; RV32IXQCI-NEXT:    lw t5, 0(a1)
-; RV32IXQCI-NEXT:    lw t4, 0(a1)
-; RV32IXQCI-NEXT:    lw t3, 0(a1)
-; RV32IXQCI-NEXT:    lw t2, 0(a1)
-; RV32IXQCI-NEXT:    lw t0, 0(a1)
-; RV32IXQCI-NEXT:    lw a7, 0(a1)
-; RV32IXQCI-NEXT:    lw a6, 0(a1)
 ; RV32IXQCI-NEXT:    lw a3, 0(a1)
-; RV32IXQCI-NEXT:    lw t1, 0(a1)
+; RV32IXQCI-NEXT:    lw a4, 0(a1)
 ; RV32IXQCI-NEXT:    lw a5, 0(a1)
-; RV32IXQCI-NEXT:    bltz t1, .LBB0_2
+; RV32IXQCI-NEXT:    qc.mvne a0, a0, a2, a2
+; RV32IXQCI-NEXT:    qc.mveq a0, a0, a3, a3
+; RV32IXQCI-NEXT:    lw a2, 0(a1)
+; RV32IXQCI-NEXT:    qc.mvgeu a0, a4, a0, a4
+; RV32IXQCI-NEXT:    lw a3, 0(a1)
+; RV32IXQCI-NEXT:    qc.mvltu a0, a0, a5, a5
+; RV32IXQCI-NEXT:    lw a4, 0(a1)
+; RV32IXQCI-NEXT:    qc.mvgeu a0, a0, a2, a2
+; RV32IXQCI-NEXT:    lw a2, 0(a1)
+; RV32IXQCI-NEXT:    qc.mvltu a0, a3, a0, a3
+; RV32IXQCI-NEXT:    lw a3, 0(a1)
+; RV32IXQCI-NEXT:    qc.mvge a0, a4, a0, a4
+; RV32IXQCI-NEXT:    lw a4, 0(a1)
+; RV32IXQCI-NEXT:    qc.mvlt a0, a0, a2, a2
+; RV32IXQCI-NEXT:    lw a2, 0(a1)
+; RV32IXQCI-NEXT:    qc.mvge a0, a0, a3, a3
+; RV32IXQCI-NEXT:    lw a3, 0(a1)
+; RV32IXQCI-NEXT:    qc.mvlt a0, a4, a0, a4
+; RV32IXQCI-NEXT:    lw a4, 0(a1)
+; RV32IXQCI-NEXT:    lw a1, 0(a1)
+; RV32IXQCI-NEXT:    blez a2, .LBB0_2
 ; RV32IXQCI-NEXT:  # %bb.1:
-; RV32IXQCI-NEXT:    li a5, 0
-; RV32IXQCI-NEXT:    qc.mveq a2, a0, a2, a0
-; RV32IXQCI-NEXT:    qc.mvne a4, a2, a4, a2
-; RV32IXQCI-NEXT:    qc.mvltu t5, t5, a4, a4
-; RV32IXQCI-NEXT:    qc.mvgeu t4, t5, t4, t5
-; RV32IXQCI-NEXT:    qc.mvltu t3, t4, t3, t4
-; RV32IXQCI-NEXT:    qc.mvgeu t2, t2, t3, t3
-; RV32IXQCI-NEXT:    qc.mvlt t0, t0, t2, t2
-; RV32IXQCI-NEXT:    qc.mvge a7, t0, a7, t0
-; RV32IXQCI-NEXT:    qc.mvlt a6, a7, a6, a7
-; RV32IXQCI-NEXT:    qc.mvge a3, a3, a6, a6
-; RV32IXQCI-NEXT:    qc.mvlt a3, a5, t1, t1
-; RV32IXQCI-NEXT:    mv a5, a3
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:  .LBB0_2:
-; RV32IXQCI-NEXT:    lw a2, 0(a1)
-; RV32IXQCI-NEXT:    lw a0, 0(a1)
-; RV32IXQCI-NEXT:    li a1, 1024
-; RV32IXQCI-NEXT:    qc.mvlt a2, a1, a2, a5
-; RV32IXQCI-NEXT:    li a1, 2046
-; RV32IXQCI-NEXT:    qc.mvltu a0, a1, t1, a2
+; RV32IXQCI-NEXT:    qc.mvlti a0, a2, 0, a3
+; RV32IXQCI-NEXT:    li a3, 1024
+; RV32IXQCI-NEXT:    qc.mvge a0, a3, a4, a4
+; RV32IXQCI-NEXT:    li a3, 2046
+; RV32IXQCI-NEXT:    qc.mvgeu a0, a3, a2, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64I-LABEL: foo:

diff  --git a/llvm/test/CodeGen/RISCV/select-cond.ll b/llvm/test/CodeGen/RISCV/select-cond.ll
index 3ca0f46e8c02f..a3c48737edc3c 100644
--- a/llvm/test/CodeGen/RISCV/select-cond.ll
+++ b/llvm/test/CodeGen/RISCV/select-cond.ll
@@ -7,7 +7,7 @@
 ; RUN:   | FileCheck %s --check-prefixes=RV32-XQCICM
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32-XQCICS
-; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCI
 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV64

diff  --git a/llvm/test/CodeGen/RISCV/select-const.ll b/llvm/test/CodeGen/RISCV/select-const.ll
index 65d10bb823418..dfac6e1630d25 100644
--- a/llvm/test/CodeGen/RISCV/select-const.ll
+++ b/llvm/test/CodeGen/RISCV/select-const.ll
@@ -5,7 +5,7 @@
 ; RUN:   | FileCheck -check-prefixes=RV32,RV32IF %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zicond -target-abi=ilp32 -verify-machineinstrs < %s \
 ; RUN:   | FileCheck -check-prefixes=RV32,RV32ZICOND %s
-; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCI
 ; RUN: llc -mtriple=riscv64 -target-abi=lp64 -verify-machineinstrs < %s \
 ; RUN:   | FileCheck -check-prefixes=RV64,RV64I %s
@@ -579,9 +579,9 @@ define i32 @select_slt_zero_constant1_constant2(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: select_slt_zero_constant1_constant2:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    srai a0, a0, 31
-; RV32IXQCI-NEXT:    andi a0, a0, 10
-; RV32IXQCI-NEXT:    addi a0, a0, -3
+; RV32IXQCI-NEXT:    li a1, -3
+; RV32IXQCI-NEXT:    qc.lilti a1, a0, 0, 7
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64-LABEL: select_slt_zero_constant1_constant2:
@@ -605,9 +605,9 @@ define i32 @select_sgt_negative_one_constant1_constant2(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: select_sgt_negative_one_constant1_constant2:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    srai a0, a0, 31
-; RV32IXQCI-NEXT:    andi a0, a0, -10
-; RV32IXQCI-NEXT:    addi a0, a0, 7
+; RV32IXQCI-NEXT:    li a1, -3
+; RV32IXQCI-NEXT:    qc.ligei a1, a0, 0, 7
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64-LABEL: select_sgt_negative_one_constant1_constant2:
@@ -653,12 +653,10 @@ define i32 @select_nonnegative_lui_addi(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: select_nonnegative_lui_addi:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    mv a1, a0
-; RV32IXQCI-NEXT:    lui a0, 4
-; RV32IXQCI-NEXT:    bgez a1, .LBB21_2
-; RV32IXQCI-NEXT:  # %bb.1:
-; RV32IXQCI-NEXT:    li a0, 25
-; RV32IXQCI-NEXT:  .LBB21_2:
+; RV32IXQCI-NEXT:    lui a2, 4
+; RV32IXQCI-NEXT:    li a1, 25
+; RV32IXQCI-NEXT:    qc.mvgei a1, a0, 0, a2
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64I-LABEL: select_nonnegative_lui_addi:
@@ -726,12 +724,10 @@ define i32 @select_nonnegative_lui_addi_swapped(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: select_nonnegative_lui_addi_swapped:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    bgez a0, .LBB22_2
-; RV32IXQCI-NEXT:  # %bb.1:
-; RV32IXQCI-NEXT:    lui a0, 4
-; RV32IXQCI-NEXT:    ret
-; RV32IXQCI-NEXT:  .LBB22_2:
-; RV32IXQCI-NEXT:    li a0, 25
+; RV32IXQCI-NEXT:    li a2, 25
+; RV32IXQCI-NEXT:    lui a1, 4
+; RV32IXQCI-NEXT:    qc.mvgei a1, a0, 0, a2
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64I-LABEL: select_nonnegative_lui_addi_swapped:
@@ -801,13 +797,13 @@ define i32 @
diff _shl_addi(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: 
diff _shl_addi:
 ; RV32IXQCI:       # %bb.0:
+; RV32IXQCI-NEXT:    lui a2, 4
+; RV32IXQCI-NEXT:    li a1, 25
 ; RV32IXQCI-NEXT:    bgez a0, .LBB23_2
 ; RV32IXQCI-NEXT:  # %bb.1:
-; RV32IXQCI-NEXT:    lui a0, 4
-; RV32IXQCI-NEXT:    addi a0, a0, 25
-; RV32IXQCI-NEXT:    ret
+; RV32IXQCI-NEXT:    addi a1, a2, 25
 ; RV32IXQCI-NEXT:  .LBB23_2:
-; RV32IXQCI-NEXT:    li a0, 25
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64I-LABEL: 
diff _shl_addi:
@@ -876,13 +872,13 @@ define i32 @
diff _shl_addi2(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: 
diff _shl_addi2:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    bgez a0, .LBB24_2
+; RV32IXQCI-NEXT:    lui a2, 4
+; RV32IXQCI-NEXT:    li a1, 25
+; RV32IXQCI-NEXT:    bltz a0, .LBB24_2
 ; RV32IXQCI-NEXT:  # %bb.1:
-; RV32IXQCI-NEXT:    li a0, 25
-; RV32IXQCI-NEXT:    ret
+; RV32IXQCI-NEXT:    addi a1, a2, 25
 ; RV32IXQCI-NEXT:  .LBB24_2:
-; RV32IXQCI-NEXT:    lui a0, 4
-; RV32IXQCI-NEXT:    addi a0, a0, 25
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64I-LABEL: 
diff _shl_addi2:
@@ -929,9 +925,10 @@ define i32 @
diff _pow2_24_16(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: 
diff _pow2_24_16:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    srai a0, a0, 31
-; RV32IXQCI-NEXT:    andi a0, a0, -8
-; RV32IXQCI-NEXT:    addi a0, a0, 24
+; RV32IXQCI-NEXT:    li a2, 24
+; RV32IXQCI-NEXT:    li a1, 16
+; RV32IXQCI-NEXT:    qc.mvgei a1, a0, 0, a2
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64-LABEL: 
diff _pow2_24_16:
@@ -955,9 +952,10 @@ define i32 @
diff _pow2_16_24(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: 
diff _pow2_16_24:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    srli a0, a0, 28
-; RV32IXQCI-NEXT:    andi a0, a0, 8
-; RV32IXQCI-NEXT:    addi a0, a0, 16
+; RV32IXQCI-NEXT:    li a2, 16
+; RV32IXQCI-NEXT:    li a1, 24
+; RV32IXQCI-NEXT:    qc.mvgei a1, a0, 0, a2
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64-LABEL: 
diff _pow2_16_24:
@@ -1008,14 +1006,14 @@ define i32 @zext_or_constant(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: zext_or_constant:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    bgez a0, .LBB27_2
+; RV32IXQCI-NEXT:    srli a2, a0, 31
+; RV32IXQCI-NEXT:    lui a1, 140
+; RV32IXQCI-NEXT:    addi a1, a1, 417
+; RV32IXQCI-NEXT:    bltz a0, .LBB27_2
 ; RV32IXQCI-NEXT:  # %bb.1:
-; RV32IXQCI-NEXT:    lui a0, 140
-; RV32IXQCI-NEXT:    addi a0, a0, 417
-; RV32IXQCI-NEXT:    ret
+; RV32IXQCI-NEXT:    xori a1, a2, 1
 ; RV32IXQCI-NEXT:  .LBB27_2:
-; RV32IXQCI-NEXT:    srli a0, a0, 31
-; RV32IXQCI-NEXT:    xori a0, a0, 1
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64I-LABEL: zext_or_constant:
@@ -1095,14 +1093,14 @@ define i32 @zext_or_constant2(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: zext_or_constant2:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    bltz a0, .LBB28_2
+; RV32IXQCI-NEXT:    srli a2, a0, 31
+; RV32IXQCI-NEXT:    lui a1, 140
+; RV32IXQCI-NEXT:    addi a1, a1, 417
+; RV32IXQCI-NEXT:    bgez a0, .LBB28_2
 ; RV32IXQCI-NEXT:  # %bb.1:
-; RV32IXQCI-NEXT:    lui a0, 140
-; RV32IXQCI-NEXT:    addi a0, a0, 417
-; RV32IXQCI-NEXT:    ret
+; RV32IXQCI-NEXT:    xori a1, a2, 1
 ; RV32IXQCI-NEXT:  .LBB28_2:
-; RV32IXQCI-NEXT:    srli a0, a0, 31
-; RV32IXQCI-NEXT:    xori a0, a0, 1
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64I-LABEL: zext_or_constant2:
@@ -1183,14 +1181,14 @@ define i32 @sext_or_constant(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: sext_or_constant:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    bgez a0, .LBB29_2
+; RV32IXQCI-NEXT:    srli a2, a0, 31
+; RV32IXQCI-NEXT:    lui a1, 140
+; RV32IXQCI-NEXT:    addi a1, a1, 417
+; RV32IXQCI-NEXT:    bltz a0, .LBB29_2
 ; RV32IXQCI-NEXT:  # %bb.1:
-; RV32IXQCI-NEXT:    lui a0, 140
-; RV32IXQCI-NEXT:    addi a0, a0, 417
-; RV32IXQCI-NEXT:    ret
+; RV32IXQCI-NEXT:    addi a1, a2, -1
 ; RV32IXQCI-NEXT:  .LBB29_2:
-; RV32IXQCI-NEXT:    srli a0, a0, 31
-; RV32IXQCI-NEXT:    addi a0, a0, -1
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64I-LABEL: sext_or_constant:
@@ -1271,14 +1269,14 @@ define i32 @sext_or_constant2(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: sext_or_constant2:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    bltz a0, .LBB30_2
+; RV32IXQCI-NEXT:    srli a2, a0, 31
+; RV32IXQCI-NEXT:    lui a1, 140
+; RV32IXQCI-NEXT:    addi a1, a1, 417
+; RV32IXQCI-NEXT:    bgez a0, .LBB30_2
 ; RV32IXQCI-NEXT:  # %bb.1:
-; RV32IXQCI-NEXT:    lui a0, 140
-; RV32IXQCI-NEXT:    addi a0, a0, 417
-; RV32IXQCI-NEXT:    ret
+; RV32IXQCI-NEXT:    addi a1, a2, -1
 ; RV32IXQCI-NEXT:  .LBB30_2:
-; RV32IXQCI-NEXT:    srli a0, a0, 31
-; RV32IXQCI-NEXT:    addi a0, a0, -1
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64I-LABEL: sext_or_constant2:
@@ -1332,9 +1330,9 @@ define i32 @select_0_6(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: select_0_6:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    srai a0, a0, 2
-; RV32IXQCI-NEXT:    srli a0, a0, 30
-; RV32IXQCI-NEXT:    slli a0, a0, 1
+; RV32IXQCI-NEXT:    li a1, 6
+; RV32IXQCI-NEXT:    qc.ligei a1, a0, 0, 0
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64-LABEL: select_0_6:
@@ -1358,9 +1356,9 @@ define i32 @select_6_0(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: select_6_0:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    srli a0, a0, 31
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    andi a0, a0, 6
+; RV32IXQCI-NEXT:    li a1, 0
+; RV32IXQCI-NEXT:    qc.ligei a1, a0, 0, 6
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64-LABEL: select_6_0:
@@ -1383,8 +1381,9 @@ define i32 @select_0_394(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: select_0_394:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    srai a0, a0, 31
-; RV32IXQCI-NEXT:    andi a0, a0, 394
+; RV32IXQCI-NEXT:    li a1, 394
+; RV32IXQCI-NEXT:    qc.ligei a1, a0, 0, 0
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64-LABEL: select_0_394:
@@ -1407,9 +1406,9 @@ define i32 @select_394_0(i32 signext %x) {
 ;
 ; RV32IXQCI-LABEL: select_394_0:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    srli a0, a0, 31
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    andi a0, a0, 394
+; RV32IXQCI-NEXT:    li a1, 394
+; RV32IXQCI-NEXT:    qc.lilti a1, a0, 0, 0
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 ;
 ; RV64-LABEL: select_394_0:

diff  --git a/llvm/test/CodeGen/RISCV/select.ll b/llvm/test/CodeGen/RISCV/select.ll
index 8273c65bf512e..1eb47e4c0ede2 100644
--- a/llvm/test/CodeGen/RISCV/select.ll
+++ b/llvm/test/CodeGen/RISCV/select.ll
@@ -4,7 +4,7 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+m,+xventanacondops -verify-machineinstrs < %s | FileCheck --check-prefixes=CHECK,RV64IMXVTCONDOPS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+m,+zicond -verify-machineinstrs < %s | FileCheck --check-prefixes=CHECK,CHECKZICOND,RV32IMZICOND %s
 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zicond -verify-machineinstrs < %s | FileCheck --check-prefixes=CHECK,CHECKZICOND,RV64IMZICOND %s
-; RUN: llc -mtriple=riscv32 -mattr=+m,+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+m,+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCI
 
 define i16 @select_xor_1(i16 %A, i8 %cond) {
@@ -44,10 +44,11 @@ define i16 @select_xor_1(i16 %A, i8 %cond) {
 ;
 ; RV32IXQCI-LABEL: select_xor_1:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    slli a1, a1, 31
-; RV32IXQCI-NEXT:    srai a1, a1, 31
-; RV32IXQCI-NEXT:    andi a1, a1, 43
-; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:    andi a1, a1, 1
+; RV32IXQCI-NEXT:    beqz a1, .LBB0_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    xori a0, a0, 43
+; RV32IXQCI-NEXT:  .LBB0_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -102,10 +103,11 @@ define i16 @select_xor_1b(i16 %A, i8 %cond) {
 ;
 ; RV32IXQCI-LABEL: select_xor_1b:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    slli a1, a1, 31
-; RV32IXQCI-NEXT:    srai a1, a1, 31
-; RV32IXQCI-NEXT:    andi a1, a1, 43
-; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:    andi a1, a1, 1
+; RV32IXQCI-NEXT:    beqz a1, .LBB1_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    xori a0, a0, 43
+; RV32IXQCI-NEXT:  .LBB1_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -148,10 +150,11 @@ define i32 @select_xor_2(i32 %A, i32 %B, i8 %cond) {
 ;
 ; RV32IXQCI-LABEL: select_xor_2:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    slli a2, a2, 31
-; RV32IXQCI-NEXT:    srai a2, a2, 31
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB2_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB2_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -196,10 +199,11 @@ define i32 @select_xor_2b(i32 %A, i32 %B, i8 %cond) {
 ;
 ; RV32IXQCI-LABEL: select_xor_2b:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    slli a2, a2, 31
-; RV32IXQCI-NEXT:    srai a2, a2, 31
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB3_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB3_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -221,9 +225,10 @@ define i16 @select_xor_3(i16 %A, i8 %cond) {
 ; RV32IXQCI-LABEL: select_xor_3:
 ; RV32IXQCI:       # %bb.0: # %entry
 ; RV32IXQCI-NEXT:    andi a1, a1, 1
-; RV32IXQCI-NEXT:    addi a1, a1, -1
-; RV32IXQCI-NEXT:    andi a1, a1, 43
-; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:    bnez a1, .LBB4_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    xori a0, a0, 43
+; RV32IXQCI-NEXT:  .LBB4_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -247,9 +252,10 @@ define i16 @select_xor_3b(i16 %A, i8 %cond) {
 ; RV32IXQCI-LABEL: select_xor_3b:
 ; RV32IXQCI:       # %bb.0: # %entry
 ; RV32IXQCI-NEXT:    andi a1, a1, 1
-; RV32IXQCI-NEXT:    addi a1, a1, -1
-; RV32IXQCI-NEXT:    andi a1, a1, 43
-; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:    bnez a1, .LBB5_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    xori a0, a0, 43
+; RV32IXQCI-NEXT:  .LBB5_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -293,9 +299,10 @@ define i32 @select_xor_4(i32 %A, i32 %B, i8 %cond) {
 ; RV32IXQCI-LABEL: select_xor_4:
 ; RV32IXQCI:       # %bb.0: # %entry
 ; RV32IXQCI-NEXT:    andi a2, a2, 1
-; RV32IXQCI-NEXT:    addi a2, a2, -1
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    bnez a2, .LBB6_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB6_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -341,9 +348,10 @@ define i32 @select_xor_4b(i32 %A, i32 %B, i8 %cond) {
 ; RV32IXQCI-LABEL: select_xor_4b:
 ; RV32IXQCI:       # %bb.0: # %entry
 ; RV32IXQCI-NEXT:    andi a2, a2, 1
-; RV32IXQCI-NEXT:    addi a2, a2, -1
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    bnez a2, .LBB7_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    xor a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB7_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -382,9 +390,12 @@ define i32 @select_xor_5(i1 zeroext %cond, i32 %x) {
 ;
 ; RV32IXQCI-LABEL: select_xor_5:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    and a0, a0, a1
-; RV32IXQCI-NEXT:    xori a0, a0, 128
+; RV32IXQCI-NEXT:    li a2, 128
+; RV32IXQCI-NEXT:    bnez a0, .LBB8_2
+; RV32IXQCI-NEXT:  # %bb.1:
+; RV32IXQCI-NEXT:    xori a2, a1, 128
+; RV32IXQCI-NEXT:  .LBB8_2:
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
   %add = xor i32 %x, 128
   %sel = select i1 %cond, i32 128, i32 %add
@@ -424,10 +435,11 @@ define i32 @select_or(i32 %A, i32 %B, i8 %cond) {
 ;
 ; RV32IXQCI-LABEL: select_or:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    slli a2, a2, 31
-; RV32IXQCI-NEXT:    srai a2, a2, 31
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB9_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB9_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -472,10 +484,11 @@ define i32 @select_or_b(i32 %A, i32 %B, i8 %cond) {
 ;
 ; RV32IXQCI-LABEL: select_or_b:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    slli a2, a2, 31
-; RV32IXQCI-NEXT:    srai a2, a2, 31
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB10_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB10_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -518,10 +531,11 @@ define i32 @select_or_1(i32 %A, i32 %B, i32 %cond) {
 ;
 ; RV32IXQCI-LABEL: select_or_1:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    slli a2, a2, 31
-; RV32IXQCI-NEXT:    srai a2, a2, 31
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB11_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB11_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i32 %cond, 1
@@ -566,10 +580,11 @@ define i32 @select_or_1b(i32 %A, i32 %B, i32 %cond) {
 ;
 ; RV32IXQCI-LABEL: select_or_1b:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    slli a2, a2, 31
-; RV32IXQCI-NEXT:    srai a2, a2, 31
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    andi a2, a2, 1
+; RV32IXQCI-NEXT:    beqz a2, .LBB12_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB12_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i32 %cond, 1
@@ -613,9 +628,10 @@ define i32 @select_or_2(i32 %A, i32 %B, i8 %cond) {
 ; RV32IXQCI-LABEL: select_or_2:
 ; RV32IXQCI:       # %bb.0: # %entry
 ; RV32IXQCI-NEXT:    andi a2, a2, 1
-; RV32IXQCI-NEXT:    addi a2, a2, -1
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    bnez a2, .LBB13_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB13_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -661,9 +677,10 @@ define i32 @select_or_2b(i32 %A, i32 %B, i8 %cond) {
 ; RV32IXQCI-LABEL: select_or_2b:
 ; RV32IXQCI:       # %bb.0: # %entry
 ; RV32IXQCI-NEXT:    andi a2, a2, 1
-; RV32IXQCI-NEXT:    addi a2, a2, -1
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    bnez a2, .LBB14_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB14_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i8 %cond, 1
@@ -707,9 +724,10 @@ define i32 @select_or_3(i32 %A, i32 %B, i32 %cond) {
 ; RV32IXQCI-LABEL: select_or_3:
 ; RV32IXQCI:       # %bb.0: # %entry
 ; RV32IXQCI-NEXT:    andi a2, a2, 1
-; RV32IXQCI-NEXT:    addi a2, a2, -1
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    bnez a2, .LBB15_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB15_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i32 %cond, 1
@@ -755,9 +773,10 @@ define i32 @select_or_3b(i32 %A, i32 %B, i32 %cond) {
 ; RV32IXQCI-LABEL: select_or_3b:
 ; RV32IXQCI:       # %bb.0: # %entry
 ; RV32IXQCI-NEXT:    andi a2, a2, 1
-; RV32IXQCI-NEXT:    addi a2, a2, -1
-; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:    bnez a2, .LBB16_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
 ; RV32IXQCI-NEXT:    or a0, a0, a1
+; RV32IXQCI-NEXT:  .LBB16_2: # %entry
 ; RV32IXQCI-NEXT:    ret
 entry:
  %and = and i32 %cond, 1
@@ -796,9 +815,12 @@ define i32 @select_or_4(i1 zeroext %cond, i32 %x) {
 ;
 ; RV32IXQCI-LABEL: select_or_4:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    and a0, a0, a1
-; RV32IXQCI-NEXT:    ori a0, a0, 128
+; RV32IXQCI-NEXT:    li a2, 128
+; RV32IXQCI-NEXT:    bnez a0, .LBB17_2
+; RV32IXQCI-NEXT:  # %bb.1:
+; RV32IXQCI-NEXT:    ori a2, a1, 128
+; RV32IXQCI-NEXT:  .LBB17_2:
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
   %add = or i32 %x, 128
   %sel = select i1 %cond, i32 128, i32 %add
@@ -840,9 +862,11 @@ define i32 @select_add_1(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_add_1:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    neg a0, a0
-; RV32IXQCI-NEXT:    and a0, a0, a1
-; RV32IXQCI-NEXT:    add a0, a0, a2
+; RV32IXQCI-NEXT:    beqz a0, .LBB18_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    add a2, a2, a1
+; RV32IXQCI-NEXT:  .LBB18_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = add i32 %a, %b
@@ -885,9 +909,11 @@ define i32 @select_add_2(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_add_2:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    and a0, a0, a2
-; RV32IXQCI-NEXT:    add a0, a0, a1
+; RV32IXQCI-NEXT:    bnez a0, .LBB19_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    add a1, a1, a2
+; RV32IXQCI-NEXT:  .LBB19_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = add i32 %a, %b
@@ -933,9 +959,11 @@ define i32 @select_add_3(i1 zeroext %cond, i32 %a) {
 ;
 ; RV32IXQCI-LABEL: select_add_3:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    andi a0, a0, 42
-; RV32IXQCI-NEXT:    add a0, a0, a1
+; RV32IXQCI-NEXT:    bnez a0, .LBB20_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    addi a1, a1, 42
+; RV32IXQCI-NEXT:  .LBB20_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = add i32 %a, 42
@@ -978,9 +1006,12 @@ define i32 @select_add_4(i1 zeroext %cond, i32 %x) {
 ;
 ; RV32IXQCI-LABEL: select_add_4:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    and a0, a0, a1
-; RV32IXQCI-NEXT:    addi a0, a0, 128
+; RV32IXQCI-NEXT:    li a2, 128
+; RV32IXQCI-NEXT:    bnez a0, .LBB21_2
+; RV32IXQCI-NEXT:  # %bb.1:
+; RV32IXQCI-NEXT:    addi a2, a1, 128
+; RV32IXQCI-NEXT:  .LBB21_2:
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
   %add = add i32 %x, 128
   %sel = select i1 %cond, i32 128, i32 %add
@@ -1029,12 +1060,14 @@ define i64 @select_add_5(i1 zeroext %cond, i64 %x) {
 ;
 ; RV32IXQCI-LABEL: select_add_5:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    addi a3, a0, -1
-; RV32IXQCI-NEXT:    and a1, a1, a3
-; RV32IXQCI-NEXT:    addi a0, a1, 128
-; RV32IXQCI-NEXT:    sltu a1, a0, a1
-; RV32IXQCI-NEXT:    and a2, a2, a3
-; RV32IXQCI-NEXT:    add a1, a1, a2
+; RV32IXQCI-NEXT:    mv a3, a0
+; RV32IXQCI-NEXT:    addi a4, a1, 128
+; RV32IXQCI-NEXT:    sltu a0, a4, a1
+; RV32IXQCI-NEXT:    add a2, a2, a0
+; RV32IXQCI-NEXT:    li a0, 128
+; RV32IXQCI-NEXT:    qc.mveqi a0, a3, 0, a4
+; RV32IXQCI-NEXT:    qc.selectieqi a3, 0, a2, 0
+; RV32IXQCI-NEXT:    mv a1, a3
 ; RV32IXQCI-NEXT:    ret
   %add = add i64 %x, 128
   %sel = select i1 %cond, i64 128, i64 %add
@@ -1093,14 +1126,15 @@ define i64 @select_add_6(i1 zeroext %cond, i64 %x) {
 ;
 ; RV32IXQCI-LABEL: select_add_6:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    addi a3, a0, -1
+; RV32IXQCI-NEXT:    mv a3, a0
 ; RV32IXQCI-NEXT:    lui a0, 14
-; RV32IXQCI-NEXT:    and a1, a1, a3
-; RV32IXQCI-NEXT:    addi a0, a0, 1005
-; RV32IXQCI-NEXT:    add a0, a0, a1
+; RV32IXQCI-NEXT:    addi a4, a0, 1005
+; RV32IXQCI-NEXT:    add a0, a1, a4
 ; RV32IXQCI-NEXT:    sltu a1, a0, a1
-; RV32IXQCI-NEXT:    and a2, a2, a3
 ; RV32IXQCI-NEXT:    add a1, a1, a2
+; RV32IXQCI-NEXT:    qc.mvnei a0, a3, 0, a4
+; RV32IXQCI-NEXT:    qc.selectieqi a3, 0, a1, 0
+; RV32IXQCI-NEXT:    mv a1, a3
 ; RV32IXQCI-NEXT:    ret
   %add = add i64 %x, 58349
   %sel = select i1 %cond, i64 58349, i64 %add
@@ -1152,9 +1186,11 @@ define i32 @select_sub_1(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_sub_1:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    sub a1, a1, a2
-; RV32IXQCI-NEXT:    qc.mveqi a1, a0, 0, a2
-; RV32IXQCI-NEXT:    mv a0, a1
+; RV32IXQCI-NEXT:    beqz a0, .LBB24_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    sub a2, a1, a2
+; RV32IXQCI-NEXT:  .LBB24_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = sub i32 %a, %b
@@ -1197,9 +1233,11 @@ define i32 @select_sub_2(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_sub_2:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    and a0, a0, a2
-; RV32IXQCI-NEXT:    sub a0, a1, a0
+; RV32IXQCI-NEXT:    bnez a0, .LBB25_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    sub a1, a1, a2
+; RV32IXQCI-NEXT:  .LBB25_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = sub i32 %a, %b
@@ -1245,9 +1283,11 @@ define i32 @select_sub_3(i1 zeroext %cond, i32 %a) {
 ;
 ; RV32IXQCI-LABEL: select_sub_3:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    andi a0, a0, 42
-; RV32IXQCI-NEXT:    sub a0, a1, a0
+; RV32IXQCI-NEXT:    bnez a0, .LBB26_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    addi a1, a1, -42
+; RV32IXQCI-NEXT:  .LBB26_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = sub i32 %a, 42
@@ -1301,10 +1341,12 @@ define i32 @select_sub_4(i1 zeroext %cond, i32 %x) {
 ;
 ; RV32IXQCI-LABEL: select_sub_4:
 ; RV32IXQCI:       # %bb.0:
+; RV32IXQCI-NEXT:    li a2, 128
+; RV32IXQCI-NEXT:    bnez a0, .LBB27_2
+; RV32IXQCI-NEXT:  # %bb.1:
 ; RV32IXQCI-NEXT:    addi a2, a1, -128
-; RV32IXQCI-NEXT:    li a1, 128
-; RV32IXQCI-NEXT:    qc.mveqi a1, a0, 0, a2
-; RV32IXQCI-NEXT:    mv a0, a1
+; RV32IXQCI-NEXT:  .LBB27_2:
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
   %add = sub i32 %x, 128
   %sel = select i1 %cond, i32 128, i32 %add
@@ -1347,9 +1389,11 @@ define i32 @select_and_1(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_and_1:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    and a1, a1, a2
-; RV32IXQCI-NEXT:    qc.mveqi a1, a0, 0, a2
-; RV32IXQCI-NEXT:    mv a0, a1
+; RV32IXQCI-NEXT:    beqz a0, .LBB28_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    and a2, a2, a1
+; RV32IXQCI-NEXT:  .LBB28_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = and i32 %a, %b
@@ -1392,9 +1436,11 @@ define i32 @select_and_2(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_and_2:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    and a2, a2, a1
-; RV32IXQCI-NEXT:    qc.mvnei a2, a0, 0, a1
-; RV32IXQCI-NEXT:    mv a0, a2
+; RV32IXQCI-NEXT:    bnez a0, .LBB29_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    and a1, a1, a2
+; RV32IXQCI-NEXT:  .LBB29_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = and i32 %a, %b
@@ -1437,9 +1483,11 @@ define i32 @select_and_3(i1 zeroext %cond, i32 %a) {
 ;
 ; RV32IXQCI-LABEL: select_and_3:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    andi a2, a1, 42
-; RV32IXQCI-NEXT:    qc.mvnei a2, a0, 0, a1
-; RV32IXQCI-NEXT:    mv a0, a2
+; RV32IXQCI-NEXT:    bnez a0, .LBB30_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    andi a1, a1, 42
+; RV32IXQCI-NEXT:  .LBB30_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = and i32 %a, 42
@@ -1626,9 +1674,11 @@ define i32 @select_udiv_3(i1 zeroext %cond, i32 %a) {
 ; RV32IXQCI-NEXT:    lui a3, 199729
 ; RV32IXQCI-NEXT:    addi a3, a3, -975
 ; RV32IXQCI-NEXT:    mulhu a2, a2, a3
-; RV32IXQCI-NEXT:    srli a2, a2, 2
-; RV32IXQCI-NEXT:    qc.mvnei a2, a0, 0, a1
-; RV32IXQCI-NEXT:    mv a0, a2
+; RV32IXQCI-NEXT:    bnez a0, .LBB33_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    srli a1, a2, 2
+; RV32IXQCI-NEXT:  .LBB33_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = udiv i32 %a, 42
@@ -1681,9 +1731,11 @@ define i32 @select_shl_1(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_shl_1:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    sll a1, a1, a2
-; RV32IXQCI-NEXT:    qc.mveqi a1, a0, 0, a2
-; RV32IXQCI-NEXT:    mv a0, a1
+; RV32IXQCI-NEXT:    beqz a0, .LBB34_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    sll a2, a1, a2
+; RV32IXQCI-NEXT:  .LBB34_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = shl i32 %a, %b
@@ -1726,9 +1778,11 @@ define i32 @select_shl_2(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_shl_2:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    and a0, a0, a2
-; RV32IXQCI-NEXT:    sll a0, a1, a0
+; RV32IXQCI-NEXT:    bnez a0, .LBB35_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    sll a1, a1, a2
+; RV32IXQCI-NEXT:  .LBB35_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = shl i32 %a, %b
@@ -1797,9 +1851,11 @@ define i32 @select_ashr_1(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_ashr_1:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    sra a1, a1, a2
-; RV32IXQCI-NEXT:    qc.mveqi a1, a0, 0, a2
-; RV32IXQCI-NEXT:    mv a0, a1
+; RV32IXQCI-NEXT:    beqz a0, .LBB37_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    sra a2, a1, a2
+; RV32IXQCI-NEXT:  .LBB37_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = ashr i32 %a, %b
@@ -1842,9 +1898,11 @@ define i32 @select_ashr_2(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_ashr_2:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    and a0, a0, a2
-; RV32IXQCI-NEXT:    sra a0, a1, a0
+; RV32IXQCI-NEXT:    bnez a0, .LBB38_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    sra a1, a1, a2
+; RV32IXQCI-NEXT:  .LBB38_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = ashr i32 %a, %b
@@ -1913,9 +1971,11 @@ define i32 @select_lshr_1(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_lshr_1:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    srl a1, a1, a2
-; RV32IXQCI-NEXT:    qc.mveqi a1, a0, 0, a2
-; RV32IXQCI-NEXT:    mv a0, a1
+; RV32IXQCI-NEXT:    beqz a0, .LBB40_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    srl a2, a1, a2
+; RV32IXQCI-NEXT:  .LBB40_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a2
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = lshr i32 %a, %b
@@ -1958,9 +2018,11 @@ define i32 @select_lshr_2(i1 zeroext %cond, i32 %a, i32 %b) {
 ;
 ; RV32IXQCI-LABEL: select_lshr_2:
 ; RV32IXQCI:       # %bb.0: # %entry
-; RV32IXQCI-NEXT:    addi a0, a0, -1
-; RV32IXQCI-NEXT:    and a0, a0, a2
-; RV32IXQCI-NEXT:    srl a0, a1, a0
+; RV32IXQCI-NEXT:    bnez a0, .LBB41_2
+; RV32IXQCI-NEXT:  # %bb.1: # %entry
+; RV32IXQCI-NEXT:    srl a1, a1, a2
+; RV32IXQCI-NEXT:  .LBB41_2: # %entry
+; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
 entry:
   %c = lshr i32 %a, %b
@@ -2304,11 +2366,13 @@ define i32 @select_cst3(i1 zeroext %cond) {
 ;
 ; RV32IXQCI-LABEL: select_cst3:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    lui a1, 7
-; RV32IXQCI-NEXT:    lui a2, 5
-; RV32IXQCI-NEXT:    addi a3, a1, 1328
-; RV32IXQCI-NEXT:    addi a1, a2, -480
-; RV32IXQCI-NEXT:    qc.mvnei a1, a0, 0, a3
+; RV32IXQCI-NEXT:    lui a2, 7
+; RV32IXQCI-NEXT:    lui a1, 5
+; RV32IXQCI-NEXT:    addi a1, a1, -480
+; RV32IXQCI-NEXT:    beqz a0, .LBB51_2
+; RV32IXQCI-NEXT:  # %bb.1:
+; RV32IXQCI-NEXT:    addi a1, a2, 1328
+; RV32IXQCI-NEXT:  .LBB51_2:
 ; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
   %ret = select i1 %cond, i32 30000, i32 20000
@@ -2370,10 +2434,12 @@ define i32 @select_cst5(i1 zeroext %cond) {
 ;
 ; RV32IXQCI-LABEL: select_cst5:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    lui a1, 1
-; RV32IXQCI-NEXT:    addi a2, a1, -2047
+; RV32IXQCI-NEXT:    lui a2, 1
 ; RV32IXQCI-NEXT:    li a1, 2047
-; RV32IXQCI-NEXT:    qc.mveqi a1, a0, 0, a2
+; RV32IXQCI-NEXT:    bnez a0, .LBB53_2
+; RV32IXQCI-NEXT:  # %bb.1:
+; RV32IXQCI-NEXT:    addi a1, a2, -2047
+; RV32IXQCI-NEXT:  .LBB53_2:
 ; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
   %ret = select i1 %cond, i32 2047, i32 2049
@@ -2417,10 +2483,12 @@ define i32 @select_cst5_invert(i1 zeroext %cond) {
 ;
 ; RV32IXQCI-LABEL: select_cst5_invert:
 ; RV32IXQCI:       # %bb.0:
-; RV32IXQCI-NEXT:    lui a1, 1
-; RV32IXQCI-NEXT:    addi a2, a1, -2047
+; RV32IXQCI-NEXT:    lui a2, 1
 ; RV32IXQCI-NEXT:    li a1, 2047
-; RV32IXQCI-NEXT:    qc.mvnei a1, a0, 0, a2
+; RV32IXQCI-NEXT:    beqz a0, .LBB54_2
+; RV32IXQCI-NEXT:  # %bb.1:
+; RV32IXQCI-NEXT:    addi a1, a2, -2047
+; RV32IXQCI-NEXT:  .LBB54_2:
 ; RV32IXQCI-NEXT:    mv a0, a1
 ; RV32IXQCI-NEXT:    ret
   %ret = select i1 %cond, i32 2049, i32 2047

diff  --git a/llvm/test/CodeGen/RISCV/xqcicli.ll b/llvm/test/CodeGen/RISCV/xqcicli.ll
index 8b976163351ae..8d4caa177513b 100644
--- a/llvm/test/CodeGen/RISCV/xqcicli.ll
+++ b/llvm/test/CodeGen/RISCV/xqcicli.ll
@@ -4,7 +4,7 @@
 ; RUN:   | FileCheck %s --check-prefixes=RV32I
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicli -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCICLI
-; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCI
 
 define i32 @select_cc_example_eq(i32 %a, i32 %b, i32 %x, i32 %y) {

diff  --git a/llvm/test/CodeGen/RISCV/xqcicm.ll b/llvm/test/CodeGen/RISCV/xqcicm.ll
index fb48301b1d8e8..8e934963c258b 100644
--- a/llvm/test/CodeGen/RISCV/xqcicm.ll
+++ b/llvm/test/CodeGen/RISCV/xqcicm.ll
@@ -6,7 +6,7 @@
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCICM
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCICM
-; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCI
 
 define i32 @select_example(i32 %cond, i32 %x, i32 %y) {

diff  --git a/llvm/test/CodeGen/RISCV/xqcics.ll b/llvm/test/CodeGen/RISCV/xqcics.ll
index 60fc98c5de663..c0839c98c1348 100644
--- a/llvm/test/CodeGen/RISCV/xqcics.ll
+++ b/llvm/test/CodeGen/RISCV/xqcics.ll
@@ -6,7 +6,7 @@
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCICS
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics,+experimental-xqcicm -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCICM
-; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli -verify-machineinstrs < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm,+experimental-xqcics,+experimental-xqcicli,+zca,+short-forward-branch-opt,+conditional-cmv-fusion -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s --check-prefixes=RV32IXQCI
 
 define i32 @select_cc_example_eq_s1(i32 %a, i32 %b, i32 %x, i32 %y) {


        


More information about the llvm-commits mailing list