[llvm] [RISCV][NFC] Prepare for Short Forward Branch of branches with immediates (PR #182456)

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 2 22:11:26 PST 2026


https://github.com/hchandel updated https://github.com/llvm/llvm-project/pull/182456

>From 131ce22aee8e026397bc589e833aca1dcd5757b4 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Tue, 17 Feb 2026 18:04:58 +0530
Subject: [PATCH 1/7] [RISCV][NFC] Prepare for Short Forward Branch of branches
 with immediates

Change-Id: I36abc2bb682302ca66cc8c3eef3677f741b7255b
---
 .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h |   3 +-
 .../Target/RISCV/RISCVExpandPseudoInsts.cpp   |  41 +++++-
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp      | 119 ++++++++++++++++--
 llvm/lib/Target/RISCV/RISCVInstrInfo.h        |   1 +
 llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td    |  80 +++++++-----
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td   |   9 +-
 6 files changed, 203 insertions(+), 50 deletions(-)

diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index cda2f95bbef78..eae00fc9595ea 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -462,7 +462,8 @@ enum OperandType : unsigned {
   // instructions to represent a value that be passed as AVL to either vsetvli
   // or vsetivli.
   OPERAND_AVL,
-
+  OPERAND_SFBRHS,
+  OPERAND_BCC_OPCODE,
   OPERAND_VMASK,
 };
 } // namespace RISCVOp
diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index 8376a9c2e2236..3efa07e6a206e 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -217,13 +217,13 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
   // We want to copy the "true" value when the condition is true which means
   // we need to invert the branch condition to jump over TrueBB when the
   // condition is false.
-  auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
-  CC = RISCVCC::getInverseBranchCondition(CC);
+
+  unsigned BranchOpCode = MI.getOperand(3).getImm();
 
   // Insert branch instruction.
-  BuildMI(MBB, MBBI, DL, TII->get(RISCVCC::getBrCond(CC)))
-      .addReg(MI.getOperand(1).getReg())
-      .addReg(MI.getOperand(2).getReg())
+  BuildMI(MBB, MBBI, DL, TII->get(BranchOpCode))
+      .add(MI.getOperand(1))
+      .add(MI.getOperand(2))
       .addMBB(MergeBB);
 
   Register DestReg = MI.getOperand(0).getReg();
@@ -345,7 +345,36 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
       MI.getOperand(5).getReg() == RISCV::X0)
     return false;
 
-  auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
+  auto BCC = MI.getOperand(3).getImm();
+  auto CC = RISCVCC::COND_EQ;
+  switch (BCC) {
+  default:
+    llvm_unreachable("Unexpected branch opcode!");
+  case RISCV::BEQ: {
+    CC = RISCVCC::COND_NE;
+    break;
+  }
+  case RISCV::BNE: {
+    CC = RISCVCC::COND_EQ;
+    break;
+  }
+  case RISCV::BLT: {
+    CC = RISCVCC::COND_GE;
+    break;
+  }
+  case RISCV::BGE: {
+    CC = RISCVCC::COND_LT;
+    break;
+  }
+  case RISCV::BLTU: {
+    CC = RISCVCC::COND_GEU;
+    break;
+  }
+  case RISCV::BGEU: {
+    CC = RISCVCC::COND_LTU;
+    break;
+  }
+  }
 
   unsigned CMovOpcode, CMovIOpcode;
   switch (CC) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index cf679d786ab61..6126b00fead6c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -970,10 +970,10 @@ MachineInstr *RISCVInstrInfo::foldMemoryOperandImpl(
                                   .add({MI.getOperand(1), MI.getOperand(2)});
 
   // Add condition code, inverting if necessary.
-  auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
+  auto BCC = MI.getOperand(3).getImm();
   if (!Invert)
-    CC = RISCVCC::getInverseBranchCondition(CC);
-  NewMI.addImm(CC);
+    BCC = RISCVCC::getInverseBranchOpcode(BCC);
+  NewMI.addImm(BCC);
 
   // Copy the false register.
   NewMI.add(FalseReg);
@@ -1286,6 +1286,49 @@ RISCVCC::CondCode RISCVCC::getInverseBranchCondition(RISCVCC::CondCode CC) {
   }
 }
 
+unsigned RISCVCC::getInverseBranchOpcode(unsigned CC) {
+  switch (CC) {
+  default:
+    llvm_unreachable("Unexpected condition code!");
+  case RISCV::BEQ:
+    return RISCV::BNE;
+  case RISCV::BNE:
+    return RISCV::BEQ;
+  case RISCV::BLT:
+    return RISCV::BGE;
+  case RISCV::BGE:
+    return RISCV::BLT;
+  case RISCV::BLTU:
+    return RISCV::BGEU;
+  case RISCV::BGEU:
+    return RISCV::BLTU;
+  case RISCV::QC_BEQI:
+    return RISCV::QC_BNEI;
+  case RISCV::QC_BNEI:
+    return RISCV::QC_BEQI;
+  case RISCV::QC_BLTI:
+    return RISCV::QC_BGEI;
+  case RISCV::QC_BGEI:
+    return RISCV::QC_BLTI;
+  case RISCV::QC_BLTUI:
+    return RISCV::QC_BGEUI;
+  case RISCV::QC_BGEUI:
+    return RISCV::QC_BLTUI;
+  case RISCV::QC_E_BEQI:
+    return RISCV::QC_E_BNEI;
+  case RISCV::QC_E_BNEI:
+    return RISCV::QC_E_BEQI;
+  case RISCV::QC_E_BLTI:
+    return RISCV::QC_E_BGEI;
+  case RISCV::QC_E_BGEI:
+    return RISCV::QC_E_BLTI;
+  case RISCV::QC_E_BLTUI:
+    return RISCV::QC_E_BGEUI;
+  case RISCV::QC_E_BGEUI:
+    return RISCV::QC_E_BLTUI;
+  }
+}
+
 bool RISCVInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
                                    MachineBasicBlock *&TBB,
                                    MachineBasicBlock *&FBB,
@@ -1958,10 +2001,10 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI,
   NewMI.add(MI.getOperand(2));
 
   // Add condition code, inverting if necessary.
-  auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
+  unsigned BCCOpcode = MI.getOperand(3).getImm();
   if (Invert)
-    CC = RISCVCC::getInverseBranchCondition(CC);
-  NewMI.addImm(CC);
+    BCCOpcode = RISCVCC::getInverseBranchOpcode(BCCOpcode);
+  NewMI.addImm(BCCOpcode);
 
   // Copy the false register.
   NewMI.add(FalseReg);
@@ -2025,6 +2068,58 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
   case RISCV::PseudoMV_FPR32INX:
     // MV is always compressible to either c.mv or c.li rd, 0.
     return STI.hasStdExtZca() ? 2 : 4;
+  case RISCV::PseudoCCMOVGPRNoX0:
+    return get(MI.getOperand(3).getImm()).getSize() + 2;
+  case RISCV::PseudoCCMOVGPR:
+  case RISCV::PseudoCCADD:
+  case RISCV::PseudoCCSUB:
+  case RISCV::PseudoCCSLL:
+  case RISCV::PseudoCCSRL:
+  case RISCV::PseudoCCSRA:
+  case RISCV::PseudoCCAND:
+  case RISCV::PseudoCCOR:
+  case RISCV::PseudoCCXOR:
+  case RISCV::PseudoCCADDI:
+  case RISCV::PseudoCCANDI:
+  case RISCV::PseudoCCORI:
+  case RISCV::PseudoCCXORI:
+  case RISCV::PseudoCCLUI:
+  case RISCV::PseudoCCSLLI:
+  case RISCV::PseudoCCSRLI:
+  case RISCV::PseudoCCSRAI:
+  case RISCV::PseudoCCADDW:
+  case RISCV::PseudoCCSUBW:
+  case RISCV::PseudoCCSLLW:
+  case RISCV::PseudoCCSRLW:
+  case RISCV::PseudoCCSRAW:
+  case RISCV::PseudoCCADDIW:
+  case RISCV::PseudoCCSLLIW:
+  case RISCV::PseudoCCSRLIW:
+  case RISCV::PseudoCCSRAIW:
+  case RISCV::PseudoCCANDN:
+  case RISCV::PseudoCCORN:
+  case RISCV::PseudoCCXNOR:
+  case RISCV::PseudoCCMAX:
+  case RISCV::PseudoCCMIN:
+  case RISCV::PseudoCCMAXU:
+  case RISCV::PseudoCCMINU:
+  case RISCV::PseudoCCMUL:
+  case RISCV::PseudoCCLB:
+  case RISCV::PseudoCCLH:
+  case RISCV::PseudoCCLW:
+  case RISCV::PseudoCCLHU:
+  case RISCV::PseudoCCLBU:
+  case RISCV::PseudoCCLWU:
+  case RISCV::PseudoCCLD:
+  case RISCV::PseudoCCQC_LI:
+    return get(MI.getOperand(3).getImm()).getSize() + 4;
+  case RISCV::PseudoCCQC_E_LI:
+  case RISCV::PseudoCCQC_E_LB:
+  case RISCV::PseudoCCQC_E_LH:
+  case RISCV::PseudoCCQC_E_LW:
+  case RISCV::PseudoCCQC_E_LHU:
+  case RISCV::PseudoCCQC_E_LBU:
+    return get(MI.getOperand(3).getImm()).getSize() + 6;
   case TargetOpcode::STACKMAP:
     // The upper bound for a stackmap intrinsic is the full length of its shadow
     return StackMapOpers(&MI).getNumPatchBytes();
@@ -3198,6 +3293,12 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
         return false;
       }
       break;
+    case RISCVOp::OPERAND_SFBRHS:
+      if (!MO.isReg() && !MO.isImm()) {
+        ErrInfo = "Expected a register or immediate operand.";
+        return false;
+      }
+      break;
     }
   }
 
@@ -4258,10 +4359,10 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI,
   case RISCV::PseudoCCMOVGPRNoX0:
   case RISCV::PseudoCCMOVGPR: {
     // CCMOV can be commuted by inverting the condition.
-    auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
-    CC = RISCVCC::getInverseBranchCondition(CC);
+    auto bcc = MI.getOperand(3).getImm();
+    bcc = RISCVCC::getInverseBranchOpcode(bcc);
     auto &WorkingMI = cloneIfNew(MI);
-    WorkingMI.getOperand(3).setImm(CC);
+    WorkingMI.getOperand(3).setImm(bcc);
     return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
                                                    OpIdx1, OpIdx2);
   }
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index 05f97332a600f..fc42ac093a22c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -64,6 +64,7 @@ enum CondCode {
 };
 
 CondCode getInverseBranchCondition(CondCode);
+unsigned getInverseBranchOpcode(unsigned CC);
 unsigned getBrCond(CondCode CC, unsigned SelectOpc = 0);
 
 } // end of namespace RISCVCC
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
index b06b9c2847168..92ff89516ed26 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
@@ -10,108 +10,132 @@
 //
 //===----------------------------------------------------------------------===//
 
+// Represents the Opcode for a branch instruction, used by SFB pseudos
+def bcc_opcode : RISCVOp<i32> {
+  let OperandType = "OPERAND_BCC_OPCODE";
+}
+
+def SFBRHS : RegisterOperand<GPR> {
+  let OperandNamespace = "RISCVOp";
+  let OperandType = "OPERAND_SFBRHS";
+}
+
+// cond -> bcc_opcode
+def CCtoRISCVBCC : SDNodeXForm<cond, [{
+  ISD::CondCode CC = N->get();
+  RISCVCC::CondCode RvCC = getRISCVCCForIntCC(CC);
+  RvCC = RISCVCC::getInverseBranchCondition(RvCC);
+  unsigned BccOpcode = RISCVCC::getBrCond(RvCC);
+  return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
+}]>;
+
+// cond_code -> bcc_opcode
+def RISCVCCtoRISCVBCC : SDNodeXForm<imm, [{
+  auto CCImm = cast<ConstantSDNode>(N)->getZExtValue();
+  auto RvCC = static_cast<RISCVCC::CondCode>(CCImm);
+  RvCC = RISCVCC::getInverseBranchCondition(RvCC);
+  unsigned BccOpcode = RISCVCC::getBrCond(RvCC);
+  return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
+}]>;
+
+def cond_as_bcc_opcode : PatLeaf<(cond), [{}], CCtoRISCVBCC>;
+
 let Predicates = [HasShortForwardBranchIALU], isSelect = 1,
-    Constraints = "$dst = $falsev", isCommutable = 1, Size = 8 in {
+    Constraints = "$dst = $falsev", isCommutable = 1 in {
 // This instruction moves $truev to $dst when the condition is true. It will
 // be expanded to control flow in RISCVExpandPseudoInsts.
 def PseudoCCMOVGPR : Pseudo<(outs GPR:$dst),
-                            (ins GPR:$lhs, GPR:$rhs, cond_code:$cc,
+                            (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$bcc,
                              GPR:$falsev, GPR:$truev),
-                            [(set GPR:$dst,
-                              (riscv_selectcc (XLenVT GPR:$lhs), GPR:$rhs,
-                                              riscv_cond:$cc,
-                                              (XLenVT GPR:$truev),
-                                              GPR:$falsev))]>,
+                            []>,
                      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
                             ReadSFBALU, ReadSFBALU]>;
 }
 
+let Predicates = [HasShortForwardBranchIALU] in
+def : Pat<(riscv_selectcc (XLenVT GPR:$lhs), GPR:$rhs, cond:$cc, (XLenVT GPR:$truev), GPR:$falsev),
+           (PseudoCCMOVGPR GPR:$lhs, GPR:$rhs, (CCtoRISCVBCC $cc), GPR:$falsev, GPR:$truev)>;
+
 // This should always expand to a branch+c.mv so the size is 6 or 4 if the
 // branch is compressible.
 let Predicates = [HasConditionalMoveFusion, NoShortForwardBranch],
-    Constraints = "$dst = $falsev", isCommutable = 1, Size = 6 in {
+    Constraints = "$dst = $falsev", isCommutable = 1 in {
 // This instruction moves $truev to $dst when the condition is true. It will
 // be expanded to control flow in RISCVExpandPseudoInsts.
 // We use GPRNoX0 because c.mv cannot encode X0.
 def PseudoCCMOVGPRNoX0 : Pseudo<(outs GPRNoX0:$dst),
-                                (ins GPR:$lhs, GPR:$rhs, cond_code:$cc,
+                                (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$bcc,
                                  GPRNoX0:$falsev, GPRNoX0:$truev),
-                                [(set GPRNoX0:$dst,
-                                  (riscv_selectcc (XLenVT GPR:$lhs), GPR:$rhs,
-                                                  riscv_cond:$cc,
-                                                  (XLenVT GPRNoX0:$truev),
-                                                  GPRNoX0:$falsev))]>,
+                                []>,
                          Sched<[]>;
 }
 
+let Predicates = [HasConditionalMoveFusion, NoShortForwardBranch] in
+def :Pat<(riscv_selectcc (XLenVT GPR:$lhs), GPR:$rhs, cond:$cc, (XLenVT GPRNoX0:$truev), GPRNoX0:$falsev),
+         (PseudoCCMOVGPRNoX0 GPR:$lhs, GPR:$rhs, (CCtoRISCVBCC $cc), GPRNoX0:$falsev, GPRNoX0:$truev)>;
+
 class SFBALU_rr
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   GPR:$rs2), []>,
       Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU,
              ReadSFBALU]> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
-  let Size = 8;
   let Constraints = "$dst = $falsev";
 }
 
 class SFBALU_ri
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   simm12_lo:$imm), []>,
       Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
-  let Size = 8;
   let Constraints = "$dst = $falsev";
 }
 
 class SFBLUI
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev,
+             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev,
                   uimm20_lui:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
-  let Size = 8;
   let Constraints = "$dst = $falsev";
 }
 
 class SFBLoad
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   simm12_lo:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 1;
   let mayStore = 0;
-  let Size = 8;
   let Constraints = "$dst = $falsev";
 }
 
 class SFBShift_ri
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   uimmlog2xlen:$imm), []>,
       Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
-  let Size = 8;
   let Constraints = "$dst = $falsev";
 }
 
 class SFBShiftW_ri
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   uimm5:$imm), []>,
       Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
-  let Size = 8;
   let Constraints = "$dst = $falsev";
 }
 
@@ -161,11 +185,11 @@ def PseudoCCXNOR : SFBALU_rr;
 
 let Predicates = [HasShortForwardBranchIALU] in
 def : Pat<(XLenVT (abs GPR:$rs1)),
-          (PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), /* COND_LT */ 2,
+          (PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), (RISCVCCtoRISCVBCC (i32 /* COND_LT */ 2)),
            (XLenVT GPR:$rs1), (XLenVT X0), (XLenVT GPR:$rs1))>;
 let Predicates = [HasShortForwardBranchIALU, IsRV64] in
 def : Pat<(sext_inreg (abs 33signbits_node:$rs1), i32),
-          (PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), /* COND_LT */ 2,
+          (PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), (RISCVCCtoRISCVBCC (i32 /* COND_LT */ 2)),
            (i64 GPR:$rs1), (i64 X0), (i64 GPR:$rs1))>;
 
 let Predicates = [HasShortForwardBranchIMinMax] in {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 6359d94de409e..44449d46e8545 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -838,34 +838,31 @@ class QCIRVInst48EJ<bits<2> func2, string opcodestr>
 
 class SFBQC_LI
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev,
+             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev,
                   simm20_li:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
-  let Size = 8;
   let Constraints = "$dst = $falsev";
 }
 
 class SFBQC_E_LI
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev,
+             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev,
                   bare_simm32:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
-  let Size = 10;
   let Constraints = "$dst = $falsev";
 }
 
 class SFBQCLoad
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   simm26:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 1;
   let mayStore = 0;
-  let Size = 10;
   let Constraints = "$dst = $falsev";
 }
 

>From 12bc297ddfe68567f513641622b4ddcc75b537e7 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Fri, 20 Feb 2026 14:10:01 +0530
Subject: [PATCH 2/7] fixup! Add comments and do some changes

Change-Id: I0013c12f847468e91693affb50726415b9a1f3a6
---
 .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h |  7 ++-
 .../Target/RISCV/RISCVExpandPseudoInsts.cpp   | 50 ++++---------------
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp      | 12 +++--
 llvm/lib/Target/RISCV/RISCVInstrInfo.h        |  2 +-
 llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td    | 42 ++++++++--------
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td   |  6 +--
 6 files changed, 49 insertions(+), 70 deletions(-)

diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index eae00fc9595ea..464006f80647c 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -462,7 +462,12 @@ enum OperandType : unsigned {
   // instructions to represent a value that be passed as AVL to either vsetvli
   // or vsetivli.
   OPERAND_AVL,
-  OPERAND_SFBRHS,
+
+  // Operand is either a register or imm, this is used by short forward branch
+  // (SFB) pseudos to enable SFB with branches on reg-reg and reg-imm compares.
+  OPERAND_SFB_RHS,
+
+  // Operand is a branch opcode, this too is used by SFB pseudos.
   OPERAND_BCC_OPCODE,
   OPERAND_VMASK,
 };
diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index 3efa07e6a206e..f706130d22e52 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -216,7 +216,8 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
 
   // We want to copy the "true" value when the condition is true which means
   // we need to invert the branch condition to jump over TrueBB when the
-  // condition is false.
+  // condition is false. We can directly use the branch opcode which has been
+  // inverted when SDNodeXform transforms were applied on it.
 
   unsigned BranchOpCode = MI.getOperand(3).getImm();
 
@@ -345,62 +346,33 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
       MI.getOperand(5).getReg() == RISCV::X0)
     return false;
 
+  // Use branch opcode to select appropriate Xqcicm instruction
   auto BCC = MI.getOperand(3).getImm();
-  auto CC = RISCVCC::COND_EQ;
-  switch (BCC) {
-  default:
-    llvm_unreachable("Unexpected branch opcode!");
-  case RISCV::BEQ: {
-    CC = RISCVCC::COND_NE;
-    break;
-  }
-  case RISCV::BNE: {
-    CC = RISCVCC::COND_EQ;
-    break;
-  }
-  case RISCV::BLT: {
-    CC = RISCVCC::COND_GE;
-    break;
-  }
-  case RISCV::BGE: {
-    CC = RISCVCC::COND_LT;
-    break;
-  }
-  case RISCV::BLTU: {
-    CC = RISCVCC::COND_GEU;
-    break;
-  }
-  case RISCV::BGEU: {
-    CC = RISCVCC::COND_LTU;
-    break;
-  }
-  }
-
   unsigned CMovOpcode, CMovIOpcode;
-  switch (CC) {
+  switch (BCC) {
   default:
-    llvm_unreachable("Unhandled CC");
-  case RISCVCC::COND_EQ:
+    return false; // Unhandled branch opcodes
+  case RISCV::BNE:
     CMovOpcode = RISCV::QC_MVEQ;
     CMovIOpcode = RISCV::QC_MVEQI;
     break;
-  case RISCVCC::COND_NE:
+  case RISCV::BEQ:
     CMovOpcode = RISCV::QC_MVNE;
     CMovIOpcode = RISCV::QC_MVNEI;
     break;
-  case RISCVCC::COND_LT:
+  case RISCV::BGE:
     CMovOpcode = RISCV::QC_MVLT;
     CMovIOpcode = RISCV::QC_MVLTI;
     break;
-  case RISCVCC::COND_GE:
+  case RISCV::BLT:
     CMovOpcode = RISCV::QC_MVGE;
     CMovIOpcode = RISCV::QC_MVGEI;
     break;
-  case RISCVCC::COND_LTU:
+  case RISCV::BGEU:
     CMovOpcode = RISCV::QC_MVLTU;
     CMovIOpcode = RISCV::QC_MVLTUI;
     break;
-  case RISCVCC::COND_GEU:
+  case RISCV::BLTU:
     CMovOpcode = RISCV::QC_MVGEU;
     CMovIOpcode = RISCV::QC_MVGEUI;
     break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 6126b00fead6c..7a1fcce7296d7 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -969,7 +969,7 @@ MachineInstr *RISCVInstrInfo::foldMemoryOperandImpl(
                                       MI.getDebugLoc(), get(PredOpc), DestReg)
                                   .add({MI.getOperand(1), MI.getOperand(2)});
 
-  // Add condition code, inverting if necessary.
+  // Add branch opcode, inverting if necessary.
   auto BCC = MI.getOperand(3).getImm();
   if (!Invert)
     BCC = RISCVCC::getInverseBranchOpcode(BCC);
@@ -1286,8 +1286,9 @@ RISCVCC::CondCode RISCVCC::getInverseBranchCondition(RISCVCC::CondCode CC) {
   }
 }
 
-unsigned RISCVCC::getInverseBranchOpcode(unsigned CC) {
-  switch (CC) {
+// Return inverse branch
+unsigned RISCVCC::getInverseBranchOpcode(unsigned BCC) {
+  switch (BCC) {
   default:
     llvm_unreachable("Unexpected condition code!");
   case RISCV::BEQ:
@@ -2000,7 +2001,7 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI,
   NewMI.add(MI.getOperand(1));
   NewMI.add(MI.getOperand(2));
 
-  // Add condition code, inverting if necessary.
+  // Add branch opcode, inverting if necessary.
   unsigned BCCOpcode = MI.getOperand(3).getImm();
   if (Invert)
     BCCOpcode = RISCVCC::getInverseBranchOpcode(BCCOpcode);
@@ -2068,6 +2069,7 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
   case RISCV::PseudoMV_FPR32INX:
     // MV is always compressible to either c.mv or c.li rd, 0.
     return STI.hasStdExtZca() ? 2 : 4;
+  // Below cases are for short forward branch pseudos
   case RISCV::PseudoCCMOVGPRNoX0:
     return get(MI.getOperand(3).getImm()).getSize() + 2;
   case RISCV::PseudoCCMOVGPR:
@@ -3293,7 +3295,7 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
         return false;
       }
       break;
-    case RISCVOp::OPERAND_SFBRHS:
+    case RISCVOp::OPERAND_SFB_RHS:
       if (!MO.isReg() && !MO.isImm()) {
         ErrInfo = "Expected a register or immediate operand.";
         return false;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
index fc42ac093a22c..4a8a8d8fa5c08 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h
@@ -64,7 +64,7 @@ enum CondCode {
 };
 
 CondCode getInverseBranchCondition(CondCode);
-unsigned getInverseBranchOpcode(unsigned CC);
+unsigned getInverseBranchOpcode(unsigned BCC);
 unsigned getBrCond(CondCode CC, unsigned SelectOpc = 0);
 
 } // end of namespace RISCVCC
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
index 92ff89516ed26..abb8740414452 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
@@ -15,9 +15,9 @@ def bcc_opcode : RISCVOp<i32> {
   let OperandType = "OPERAND_BCC_OPCODE";
 }
 
-def SFBRHS : RegisterOperand<GPR> {
+def sfb_rhs : RegisterOperand<GPR> {
   let OperandNamespace = "RISCVOp";
-  let OperandType = "OPERAND_SFBRHS";
+  let OperandType = "OPERAND_SFB_RHS";
 }
 
 // cond -> bcc_opcode
@@ -29,23 +29,14 @@ def CCtoRISCVBCC : SDNodeXForm<cond, [{
   return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
 }]>;
 
-// cond_code -> bcc_opcode
-def RISCVCCtoRISCVBCC : SDNodeXForm<imm, [{
-  auto CCImm = cast<ConstantSDNode>(N)->getZExtValue();
-  auto RvCC = static_cast<RISCVCC::CondCode>(CCImm);
-  RvCC = RISCVCC::getInverseBranchCondition(RvCC);
-  unsigned BccOpcode = RISCVCC::getBrCond(RvCC);
-  return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
-}]>;
-
-def cond_as_bcc_opcode : PatLeaf<(cond), [{}], CCtoRISCVBCC>;
-
+// 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,
     Constraints = "$dst = $falsev", isCommutable = 1 in {
 // This instruction moves $truev to $dst when the condition is true. It will
 // be expanded to control flow in RISCVExpandPseudoInsts.
 def PseudoCCMOVGPR : Pseudo<(outs GPR:$dst),
-                            (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$bcc,
+                            (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$bcc,
                              GPR:$falsev, GPR:$truev),
                             []>,
                      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
@@ -64,7 +55,7 @@ let Predicates = [HasConditionalMoveFusion, NoShortForwardBranch],
 // be expanded to control flow in RISCVExpandPseudoInsts.
 // We use GPRNoX0 because c.mv cannot encode X0.
 def PseudoCCMOVGPRNoX0 : Pseudo<(outs GPRNoX0:$dst),
-                                (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$bcc,
+                                (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$bcc,
                                  GPRNoX0:$falsev, GPRNoX0:$truev),
                                 []>,
                          Sched<[]>;
@@ -76,7 +67,7 @@ def :Pat<(riscv_selectcc (XLenVT GPR:$lhs), GPR:$rhs, cond:$cc, (XLenVT GPRNoX0:
 
 class SFBALU_rr
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   GPR:$rs2), []>,
       Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU,
              ReadSFBALU]> {
@@ -88,7 +79,7 @@ class SFBALU_rr
 
 class SFBALU_ri
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   simm12_lo:$imm), []>,
       Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
   let hasSideEffects = 0;
@@ -99,7 +90,7 @@ class SFBALU_ri
 
 class SFBLUI
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev,
                   uimm20_lui:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
@@ -109,7 +100,7 @@ class SFBLUI
 
 class SFBLoad
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   simm12_lo:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 1;
@@ -119,7 +110,7 @@ class SFBLoad
 
 class SFBShift_ri
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   uimmlog2xlen:$imm), []>,
       Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
   let hasSideEffects = 0;
@@ -130,7 +121,7 @@ class SFBShift_ri
 
 class SFBShiftW_ri
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   uimm5:$imm), []>,
       Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
   let hasSideEffects = 0;
@@ -183,6 +174,15 @@ def PseudoCCORN  : SFBALU_rr;
 def PseudoCCXNOR : SFBALU_rr;
 }
 
+// imm -> bcc_opcode
+def RISCVCCtoRISCVBCC : SDNodeXForm<imm, [{
+  auto CCImm = cast<ConstantSDNode>(N)->getZExtValue();
+  auto RvCC = static_cast<RISCVCC::CondCode>(CCImm);
+  RvCC = RISCVCC::getInverseBranchCondition(RvCC);
+  unsigned BccOpcode = RISCVCC::getBrCond(RvCC);
+  return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
+}]>;
+
 let Predicates = [HasShortForwardBranchIALU] in
 def : Pat<(XLenVT (abs GPR:$rs1)),
           (PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), (RISCVCCtoRISCVBCC (i32 /* COND_LT */ 2)),
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 44449d46e8545..9e42111b2c773 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -838,7 +838,7 @@ class QCIRVInst48EJ<bits<2> func2, string opcodestr>
 
 class SFBQC_LI
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev,
                   simm20_li:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
@@ -848,7 +848,7 @@ class SFBQC_LI
 
 class SFBQC_E_LI
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev,
                   bare_simm32:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
@@ -858,7 +858,7 @@ class SFBQC_E_LI
 
 class SFBQCLoad
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, SFBRHS:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
                   simm26:$imm), []> {
   let hasSideEffects = 0;
   let mayLoad = 1;

>From 66e91a2aaad06810558c93d140d02910750d5a7b Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Mon, 23 Feb 2026 12:19:20 +0530
Subject: [PATCH 3/7] fixup! Address comments

Change-Id: I91f7c565eb09411068d2f301f71d39520dc99b1b
---
 llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp | 7 ++-----
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp         | 8 ++++----
 2 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index f706130d22e52..d14f88e419190 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -214,11 +214,8 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
   MF->insert(++MBB.getIterator(), TrueBB);
   MF->insert(++TrueBB->getIterator(), MergeBB);
 
-  // We want to copy the "true" value when the condition is true which means
-  // we need to invert the branch condition to jump over TrueBB when the
-  // condition is false. We can directly use the branch opcode which has been
-  // inverted when SDNodeXform transforms were applied on it.
-
+  // We want to copy the "true" value only when the branch is executed.
+  // The SDNodeXform is responsible for the inversion.
   unsigned BranchOpCode = MI.getOperand(3).getImm();
 
   // Insert branch instruction.
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index f9137428c9fdf..5c6271ee95855 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -1299,7 +1299,7 @@ RISCVCC::CondCode RISCVCC::getInverseBranchCondition(RISCVCC::CondCode CC) {
 unsigned RISCVCC::getInverseBranchOpcode(unsigned BCC) {
   switch (BCC) {
   default:
-    llvm_unreachable("Unexpected condition code!");
+    llvm_unreachable("Unexpected branch opcode!");
   case RISCV::BEQ:
     return RISCV::BNE;
   case RISCV::BNE:
@@ -4375,10 +4375,10 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI,
   case RISCV::PseudoCCMOVGPRNoX0:
   case RISCV::PseudoCCMOVGPR: {
     // CCMOV can be commuted by inverting the condition.
-    auto bcc = MI.getOperand(3).getImm();
-    bcc = RISCVCC::getInverseBranchOpcode(bcc);
+    auto BCC = MI.getOperand(3).getImm();
+    BCC = RISCVCC::getInverseBranchOpcode(BCC);
     auto &WorkingMI = cloneIfNew(MI);
-    WorkingMI.getOperand(3).setImm(bcc);
+    WorkingMI.getOperand(3).setImm(BCC);
     return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
                                                    OpIdx1, OpIdx2);
   }

>From c46e026a49382cb95176d88bc1bd6873d0848e8f Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Mon, 23 Feb 2026 12:35:23 +0530
Subject: [PATCH 4/7] fixup! Update RISCVInstrInfoXAndes.td

Change-Id: I6357eb4ba1ece73a199fb7fcec123c2de5bc3705
---
 llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
index 899ed6f67a348..c4370bd9a9e89 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -937,7 +937,7 @@ defm : VPatTernaryVD4DOT_VV<"int_riscv_nds_vd4dotsu", "PseudoNDS_VD4DOTSU",
 
 class SFBNDS_BFO
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$bcc, GPR:$falsev, GPR:$rs1,
                   uimmlog2xlen:$msb, uimmlog2xlen:$lsb), []>,
       Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU,
              ReadSFBALU]> {

>From 74eb980dcb65469d735d1fe3cfd28bb584d5339d Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Fri, 27 Feb 2026 15:34:26 +0530
Subject: [PATCH 5/7] fixup! Change ordering of operands in SFB pseudos

Change-Id: Iea20068e2bffac6ade98fd02680731025ad98ff8
---
 .../Target/RISCV/RISCVExpandPseudoInsts.cpp   | 42 ++++++------
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp      | 64 ++++++++++---------
 llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td    | 58 ++++++++---------
 llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td   | 12 ++--
 llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp     | 24 +++----
 llvm/test/CodeGen/RISCV/opt-w-instrs.mir      |  8 +--
 6 files changed, 105 insertions(+), 103 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index d14f88e419190..dee511525b479 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -216,22 +216,22 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
 
   // We want to copy the "true" value only when the branch is executed.
   // The SDNodeXform is responsible for the inversion.
-  unsigned BranchOpCode = MI.getOperand(3).getImm();
+  unsigned BranchOpCode = MI.getOperand(MI.getNumOperands() - 3).getImm();
 
   // Insert branch instruction.
   BuildMI(MBB, MBBI, DL, TII->get(BranchOpCode))
-      .add(MI.getOperand(1))
-      .add(MI.getOperand(2))
+      .add(MI.getOperand(MI.getNumOperands() - 2))
+      .add(MI.getOperand(MI.getNumOperands() - 1))
       .addMBB(MergeBB);
 
   Register DestReg = MI.getOperand(0).getReg();
-  assert(MI.getOperand(4).getReg() == DestReg);
+  assert(MI.getOperand(1).getReg() == DestReg);
 
   if (MI.getOpcode() == RISCV::PseudoCCMOVGPR ||
       MI.getOpcode() == RISCV::PseudoCCMOVGPRNoX0) {
     // Add MV.
     BuildMI(TrueBB, DL, TII->get(RISCV::ADDI), DestReg)
-        .add(MI.getOperand(5))
+        .add(MI.getOperand(2))
         .addImm(0);
   } else {
     unsigned NewOpc;
@@ -293,16 +293,16 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
 
     if (NewOpc == RISCV::NDS_BFOZ || NewOpc == RISCV::NDS_BFOS) {
       BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
-          .add(MI.getOperand(5))
-          .add(MI.getOperand(6))
-          .add(MI.getOperand(7));
+          .add(MI.getOperand(2))
+          .add(MI.getOperand(3))
+          .add(MI.getOperand(4));
     } else if (NewOpc == RISCV::LUI || NewOpc == RISCV::QC_LI ||
                NewOpc == RISCV::QC_E_LI) {
-      BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg).add(MI.getOperand(5));
+      BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg).add(MI.getOperand(2));
     } else {
       BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
-          .add(MI.getOperand(5))
-          .add(MI.getOperand(6));
+          .add(MI.getOperand(2))
+          .add(MI.getOperand(3));
     }
   }
 
@@ -338,13 +338,13 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
     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)
+  if (MI.getOperand(MI.getNumOperands() - 2).getReg() == RISCV::X0 ||
+      MI.getOperand(1).getReg() == RISCV::X0 ||
+      MI.getOperand(2).getReg() == RISCV::X0)
     return false;
 
   // Use branch opcode to select appropriate Xqcicm instruction
-  auto BCC = MI.getOperand(3).getImm();
+  auto BCC = MI.getOperand(MI.getNumOperands() - 3).getImm();
   unsigned CMovOpcode, CMovIOpcode;
   switch (BCC) {
   default:
@@ -375,17 +375,17 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
     break;
   }
 
-  if (MI.getOperand(2).getReg() == RISCV::X0) {
+  if (MI.getOperand(MI.getNumOperands() - 1).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())
+        .addReg(MI.getOperand(MI.getNumOperands() - 2).getReg())
         .addImm(0)
-        .addReg(MI.getOperand(5).getReg());
+        .addReg(MI.getOperand(2).getReg());
 
     MI.eraseFromParent();
     return true;
@@ -397,10 +397,10 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
   // $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());
+      .addReg(MI.getOperand(MI.getNumOperands() - 2).getReg())
+      .addReg(MI.getOperand(MI.getNumOperands() - 1).getReg())
+      .addReg(MI.getOperand(2).getReg());
   MI.eraseFromParent();
   return true;
 }
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 5c6271ee95855..fb0a551ea5567 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -963,11 +963,11 @@ MachineInstr *RISCVInstrInfo::foldMemoryOperandImpl(
     return nullptr;
 
   MachineRegisterInfo &MRI = MF.getRegInfo();
-  if (Ops.size() != 1 || (Ops[0] != 4 && Ops[0] != 5))
+  if (Ops.size() != 1 || (Ops[0] != 1 && Ops[0] != 2))
     return nullptr;
 
-  bool Invert = Ops[0] == 5;
-  const MachineOperand &FalseReg = MI.getOperand(!Invert ? 5 : 4);
+  bool Invert = Ops[0] == 2;
+  const MachineOperand &FalseReg = MI.getOperand(!Invert ? 2 : 1);
   Register DestReg = MI.getOperand(0).getReg();
   const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
   if (!MRI.constrainRegClass(DestReg, PreviousClass))
@@ -975,14 +975,7 @@ MachineInstr *RISCVInstrInfo::foldMemoryOperandImpl(
 
   // Create a new predicated version of DefMI.
   MachineInstrBuilder NewMI = BuildMI(*MI.getParent(), InsertPt,
-                                      MI.getDebugLoc(), get(PredOpc), DestReg)
-                                  .add({MI.getOperand(1), MI.getOperand(2)});
-
-  // Add branch opcode, inverting if necessary.
-  auto BCC = MI.getOperand(3).getImm();
-  if (!Invert)
-    BCC = RISCVCC::getInverseBranchOpcode(BCC);
-  NewMI.addImm(BCC);
+                                      MI.getDebugLoc(), get(PredOpc), DestReg);
 
   // Copy the false register.
   NewMI.add(FalseReg);
@@ -992,6 +985,15 @@ MachineInstr *RISCVInstrInfo::foldMemoryOperandImpl(
   for (unsigned i = 1, e = DefDesc.getNumOperands(); i != e; ++i)
     NewMI.add(LoadMI.getOperand(i));
 
+  // Add branch opcode, inverting if necessary.
+  auto BCC = MI.getOperand(MI.getNumOperands() - 3).getImm();
+  if (!Invert)
+    BCC = RISCVCC::getInverseBranchOpcode(BCC);
+  NewMI.addImm(BCC);
+
+  // Copy condition portion
+  NewMI.add({MI.getOperand(MI.getNumOperands() - 2),
+             MI.getOperand(MI.getNumOperands() - 1)});
   NewMI.cloneMemRefs(LoadMI);
   return NewMI;
 }
@@ -1970,15 +1972,15 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI,
 
   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
   MachineInstr *DefMI =
-      canFoldAsPredicatedOp(MI.getOperand(5).getReg(), MRI, this, STI);
+      canFoldAsPredicatedOp(MI.getOperand(2).getReg(), MRI, this, STI);
   bool Invert = !DefMI;
   if (!DefMI)
-    DefMI = canFoldAsPredicatedOp(MI.getOperand(4).getReg(), MRI, this, STI);
+    DefMI = canFoldAsPredicatedOp(MI.getOperand(1).getReg(), MRI, this, STI);
   if (!DefMI)
     return nullptr;
 
   // Find new register class to use.
-  MachineOperand FalseReg = MI.getOperand(Invert ? 5 : 4);
+  MachineOperand FalseReg = MI.getOperand(Invert ? 2 : 1);
   Register DestReg = MI.getOperand(0).getReg();
   const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
   if (!MRI.constrainRegClass(DestReg, PreviousClass))
@@ -1991,16 +1993,6 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI,
   MachineInstrBuilder NewMI =
       BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(PredOpc), DestReg);
 
-  // Copy the condition portion.
-  NewMI.add(MI.getOperand(1));
-  NewMI.add(MI.getOperand(2));
-
-  // Add branch opcode, inverting if necessary.
-  unsigned BCCOpcode = MI.getOperand(3).getImm();
-  if (Invert)
-    BCCOpcode = RISCVCC::getInverseBranchOpcode(BCCOpcode);
-  NewMI.addImm(BCCOpcode);
-
   // Copy the false register.
   NewMI.add(FalseReg);
 
@@ -2009,6 +2001,16 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI,
   for (unsigned i = 1, e = DefDesc.getNumOperands(); i != e; ++i)
     NewMI.add(DefMI->getOperand(i));
 
+  // Add branch opcode, inverting if necessary.
+  unsigned BCCOpcode = MI.getOperand(MI.getNumOperands() - 3).getImm();
+  if (Invert)
+    BCCOpcode = RISCVCC::getInverseBranchOpcode(BCCOpcode);
+  NewMI.addImm(BCCOpcode);
+
+  // Copy the condition portion.
+  NewMI.add(MI.getOperand(MI.getNumOperands() - 2));
+  NewMI.add(MI.getOperand(MI.getNumOperands() - 1));
+
   // Update SeenMIs set: register newly created MI and erase removed DefMI.
   SeenMIs.insert(NewMI);
   SeenMIs.erase(DefMI);
@@ -2065,7 +2067,7 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
     return STI.hasStdExtZca() ? 2 : 4;
   // Below cases are for short forward branch pseudos
   case RISCV::PseudoCCMOVGPRNoX0:
-    return get(MI.getOperand(3).getImm()).getSize() + 2;
+    return get(MI.getOperand(MI.getNumOperands() - 3).getImm()).getSize() + 2;
   case RISCV::PseudoCCMOVGPR:
   case RISCV::PseudoCCADD:
   case RISCV::PseudoCCSUB:
@@ -2108,14 +2110,14 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
   case RISCV::PseudoCCLWU:
   case RISCV::PseudoCCLD:
   case RISCV::PseudoCCQC_LI:
-    return get(MI.getOperand(3).getImm()).getSize() + 4;
+    return get(MI.getOperand(MI.getNumOperands() - 3).getImm()).getSize() + 4;
   case RISCV::PseudoCCQC_E_LI:
   case RISCV::PseudoCCQC_E_LB:
   case RISCV::PseudoCCQC_E_LH:
   case RISCV::PseudoCCQC_E_LW:
   case RISCV::PseudoCCQC_E_LHU:
   case RISCV::PseudoCCQC_E_LBU:
-    return get(MI.getOperand(3).getImm()).getSize() + 6;
+    return get(MI.getOperand(MI.getNumOperands() - 3).getImm()).getSize() + 6;
   case TargetOpcode::STACKMAP:
     // The upper bound for a stackmap intrinsic is the full length of its shadow
     return StackMapOpers(&MI).getNumPatchBytes();
@@ -4146,8 +4148,8 @@ bool RISCVInstrInfo::findCommutedOpIndices(const MachineInstr &MI,
     return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
   case RISCV::PseudoCCMOVGPRNoX0:
   case RISCV::PseudoCCMOVGPR:
-    // Operands 4 and 5 are commutable.
-    return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 4, 5);
+    // Operands 1 and 2 are commutable.
+    return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
   case CASE_RVV_OPCODE(VADD_VV):
   case CASE_RVV_OPCODE(VAND_VV):
   case CASE_RVV_OPCODE(VOR_VV):
@@ -4375,10 +4377,10 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI,
   case RISCV::PseudoCCMOVGPRNoX0:
   case RISCV::PseudoCCMOVGPR: {
     // CCMOV can be commuted by inverting the condition.
-    auto BCC = MI.getOperand(3).getImm();
+    auto BCC = MI.getOperand(MI.getNumOperands() - 3).getImm();
     BCC = RISCVCC::getInverseBranchOpcode(BCC);
     auto &WorkingMI = cloneIfNew(MI);
-    WorkingMI.getOperand(3).setImm(BCC);
+    WorkingMI.getOperand(MI.getNumOperands() - 3).setImm(BCC);
     return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
                                                    OpIdx1, OpIdx2);
   }
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
index abb8740414452..2cf8a46acaf2a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
@@ -36,16 +36,16 @@ let Predicates = [HasShortForwardBranchIALU], isSelect = 1,
 // This instruction moves $truev to $dst when the condition is true. It will
 // be expanded to control flow in RISCVExpandPseudoInsts.
 def PseudoCCMOVGPR : Pseudo<(outs GPR:$dst),
-                            (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$bcc,
-                             GPR:$falsev, GPR:$truev),
+                            (ins GPR:$falsev, GPR:$truev, bcc_opcode:$bcc,
+                             GPR:$lhs, sfb_rhs:$rhs),
                             []>,
-                     Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
-                            ReadSFBALU, ReadSFBALU]>;
+                     Sched<[WriteSFB, ReadSFBALU, ReadSFBALU,
+                            ReadSFBJmp, ReadSFBJmp]>;
 }
 
 let Predicates = [HasShortForwardBranchIALU] in
 def : Pat<(riscv_selectcc (XLenVT GPR:$lhs), GPR:$rhs, cond:$cc, (XLenVT GPR:$truev), GPR:$falsev),
-           (PseudoCCMOVGPR GPR:$lhs, GPR:$rhs, (CCtoRISCVBCC $cc), GPR:$falsev, GPR:$truev)>;
+           (PseudoCCMOVGPR GPR:$falsev, GPR:$truev, (CCtoRISCVBCC $cc), GPR:$lhs, GPR:$rhs)>;
 
 // This should always expand to a branch+c.mv so the size is 6 or 4 if the
 // branch is compressible.
@@ -55,22 +55,22 @@ let Predicates = [HasConditionalMoveFusion, NoShortForwardBranch],
 // be expanded to control flow in RISCVExpandPseudoInsts.
 // We use GPRNoX0 because c.mv cannot encode X0.
 def PseudoCCMOVGPRNoX0 : Pseudo<(outs GPRNoX0:$dst),
-                                (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$bcc,
-                                 GPRNoX0:$falsev, GPRNoX0:$truev),
+                                (ins GPRNoX0:$falsev, GPRNoX0:$truev, bcc_opcode:$bcc,
+                                 GPR:$lhs, sfb_rhs:$rhs),
                                 []>,
                          Sched<[]>;
 }
 
 let Predicates = [HasConditionalMoveFusion, NoShortForwardBranch] in
 def :Pat<(riscv_selectcc (XLenVT GPR:$lhs), GPR:$rhs, cond:$cc, (XLenVT GPRNoX0:$truev), GPRNoX0:$falsev),
-         (PseudoCCMOVGPRNoX0 GPR:$lhs, GPR:$rhs, (CCtoRISCVBCC $cc), GPRNoX0:$falsev, GPRNoX0:$truev)>;
+         (PseudoCCMOVGPRNoX0 GPRNoX0:$falsev, GPRNoX0:$truev, (CCtoRISCVBCC $cc), GPR:$lhs, GPR:$rhs )>;
 
 class SFBALU_rr
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
-                  GPR:$rs2), []>,
-      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU,
-             ReadSFBALU]> {
+             (ins GPR:$falsev, GPR:$rs1, GPR:$rs2, bcc_opcode:$bcc,
+                  GPR:$lhs, sfb_rhs:$rhs), []>,
+      Sched<[WriteSFB, ReadSFBALU, ReadSFBALU,
+             ReadSFBALU, ReadSFBJmp, ReadSFBJmp]> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
@@ -79,9 +79,9 @@ class SFBALU_rr
 
 class SFBALU_ri
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
-                  simm12_lo:$imm), []>,
-      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
+             (ins GPR:$falsev, GPR:$rs1, simm12_lo:$imm, bcc_opcode:$bcc,
+                  GPR:$lhs, sfb_rhs:$rhs), []>,
+      Sched<[WriteSFB, ReadSFBALU, ReadSFBALU, ReadSFBJmp, ReadSFBJmp]> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
@@ -90,8 +90,8 @@ class SFBALU_ri
 
 class SFBLUI
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev,
-                  uimm20_lui:$imm), []> {
+             (ins GPR:$falsev, uimm20_lui:$imm, bcc_opcode:$bcc,
+                  GPR:$lhs, sfb_rhs:$rhs), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
@@ -100,8 +100,8 @@ class SFBLUI
 
 class SFBLoad
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
-                  simm12_lo:$imm), []> {
+             (ins GPR:$falsev, GPR:$rs1, simm12_lo:$imm, bcc_opcode:$bcc,
+                  GPR:$lhs, sfb_rhs:$rhs), []> {
   let hasSideEffects = 0;
   let mayLoad = 1;
   let mayStore = 0;
@@ -110,9 +110,9 @@ class SFBLoad
 
 class SFBShift_ri
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
-                  uimmlog2xlen:$imm), []>,
-      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
+             (ins GPR:$falsev, GPR:$rs1, uimmlog2xlen:$imm, bcc_opcode:$bcc,
+                  GPR:$lhs, sfb_rhs:$rhs), []>,
+      Sched<[WriteSFB, ReadSFBALU, ReadSFBALU, ReadSFBJmp, ReadSFBJmp]> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
@@ -121,9 +121,9 @@ class SFBShift_ri
 
 class SFBShiftW_ri
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
-                  uimm5:$imm), []>,
-      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU]> {
+             (ins GPR:$falsev, GPR:$rs1, uimm5:$imm, bcc_opcode:$bcc,
+                  GPR:$lhs, sfb_rhs:$rhs), []>,
+      Sched<[WriteSFB, ReadSFBALU, ReadSFBALU, ReadSFBJmp, ReadSFBJmp]> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
@@ -185,12 +185,12 @@ def RISCVCCtoRISCVBCC : SDNodeXForm<imm, [{
 
 let Predicates = [HasShortForwardBranchIALU] in
 def : Pat<(XLenVT (abs GPR:$rs1)),
-          (PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), (RISCVCCtoRISCVBCC (i32 /* COND_LT */ 2)),
-           (XLenVT GPR:$rs1), (XLenVT X0), (XLenVT GPR:$rs1))>;
+          (PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), (XLenVT GPR:$rs1),
+          (RISCVCCtoRISCVBCC (i32 /* COND_LT */ 2)),(XLenVT GPR:$rs1), (XLenVT X0))>;
 let Predicates = [HasShortForwardBranchIALU, IsRV64] in
 def : Pat<(sext_inreg (abs 33signbits_node:$rs1), i32),
-          (PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), (RISCVCCtoRISCVBCC (i32 /* COND_LT */ 2)),
-           (i64 GPR:$rs1), (i64 X0), (i64 GPR:$rs1))>;
+          (PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), (i64 GPR:$rs1), (RISCVCCtoRISCVBCC (i32 /* COND_LT */ 2)),
+           (i64 GPR:$rs1), (i64 X0))>;
 
 let Predicates = [HasShortForwardBranchIMinMax] in {
 def PseudoCCMAX : SFBALU_rr;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 698b0550b2560..c2051973be186 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -838,8 +838,8 @@ class QCIRVInst48EJ<bits<2> func2, string opcodestr>
 
 class SFBQC_LI
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev,
-                  simm20_li:$imm), []> {
+             (ins GPR:$falsev, simm20_li:$imm, bcc_opcode:$bcc,
+                  GPR:$lhs, sfb_rhs:$rhs), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
@@ -848,8 +848,8 @@ class SFBQC_LI
 
 class SFBQC_E_LI
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev,
-                  bare_simm32:$imm), []> {
+             (ins GPR:$falsev, bare_simm32:$imm, bcc_opcode:$bcc,
+                  GPR:$lhs, sfb_rhs:$rhs), []> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;
@@ -858,8 +858,8 @@ class SFBQC_E_LI
 
 class SFBQCLoad
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$cc, GPR:$falsev, GPR:$rs1,
-                  simm26:$imm), []> {
+             (ins GPR:$falsev, GPR:$rs1, simm26:$imm, bcc_opcode:$bcc,
+                  GPR:$lhs, sfb_rhs:$rhs), []> {
   let hasSideEffects = 0;
   let mayLoad = 1;
   let mayStore = 0;
diff --git a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
index 8baae84111a9c..56dfbcb060115 100644
--- a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
+++ b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
@@ -342,10 +342,10 @@ static bool hasAllNBitUsers(const MachineInstr &OrigMI,
 
       case RISCV::PseudoCCMOVGPR:
       case RISCV::PseudoCCMOVGPRNoX0:
-        // Either operand 4 or operand 5 is returned by this instruction. If
+        // Either operand 1 or operand 2 is returned by this instruction. If
         // only the lower word of the result is used, then only the lower word
-        // of operand 4 and 5 is used.
-        if (OpIdx != 4 && OpIdx != 5)
+        // of operand 1 and 2 is used.
+        if (OpIdx != 1 && OpIdx != 2)
           return false;
         Worklist.emplace_back(UserMI, Bits);
         break;
@@ -557,9 +557,9 @@ static bool isSignExtendedW(Register SrcReg, const RISCVSubtarget &ST,
     case RISCV::PseudoCCSLLIW:
     case RISCV::PseudoCCSRLIW:
     case RISCV::PseudoCCSRAIW:
-      // Returns operand 4 or an ADDW/SUBW/etc. of operands 5 and 6. We only
-      // need to check if operand 4 is sign extended.
-      if (!AddRegToWorkList(MI->getOperand(4).getReg()))
+      // Returns operand 1 or an ADDW/SUBW/etc. of operands 2 and 3. We only
+      // need to check if operand 1 is sign extended.
+      if (!AddRegToWorkList(MI->getOperand(1).getReg()))
         return false;
       break;
     case RISCV::REMU:
@@ -586,8 +586,8 @@ static bool isSignExtendedW(Register SrcReg, const RISCVSubtarget &ST,
       // MIN, MAX, or PHI is also sign-extended.
 
       // The input registers for PHI are operand 1, 3, ...
-      // The input registers for PseudoCCMOVGPR(NoX0) are 4 and 5.
-      // The input registers for PseudoCCAND/OR/XOR are 4, 5, and 6.
+      // The input registers for PseudoCCMOVGPR(NoX0) are 1 and 2.
+      // The input registers for PseudoCCAND/OR/XOR are 1, 2, and 3.
       // The input registers for others are operand 1 and 2.
       unsigned B = 1, E = 3, D = 1;
       switch (MI->getOpcode()) {
@@ -597,8 +597,8 @@ static bool isSignExtendedW(Register SrcReg, const RISCVSubtarget &ST,
         break;
       case RISCV::PseudoCCMOVGPR:
       case RISCV::PseudoCCMOVGPRNoX0:
-        B = 4;
-        E = 6;
+        B = 1;
+        E = 3;
         break;
       case RISCV::PseudoCCAND:
       case RISCV::PseudoCCOR:
@@ -606,8 +606,8 @@ static bool isSignExtendedW(Register SrcReg, const RISCVSubtarget &ST,
       case RISCV::PseudoCCANDN:
       case RISCV::PseudoCCORN:
       case RISCV::PseudoCCXNOR:
-        B = 4;
-        E = 7;
+        B = 1;
+        E = 4;
         break;
        }
 
diff --git a/llvm/test/CodeGen/RISCV/opt-w-instrs.mir b/llvm/test/CodeGen/RISCV/opt-w-instrs.mir
index 47407c2270ead..fa961ea1fce5a 100644
--- a/llvm/test/CodeGen/RISCV/opt-w-instrs.mir
+++ b/llvm/test/CodeGen/RISCV/opt-w-instrs.mir
@@ -123,7 +123,7 @@ body:             |
     ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
     ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnox0 = COPY $x12
     ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gprnox0 = COPY $x13
-    ; CHECK-NEXT: [[PseudoCCMOVGPRNoX0_:%[0-9]+]]:gprnox0 = PseudoCCMOVGPRNoX0 [[COPY]], [[COPY1]], 1, [[COPY2]], [[COPY3]]
+    ; CHECK-NEXT: [[PseudoCCMOVGPRNoX0_:%[0-9]+]]:gprnox0 = PseudoCCMOVGPRNoX0 [[COPY2]], [[COPY3]], 1, [[COPY]], [[COPY1]]
     ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[PseudoCCMOVGPRNoX0_]], 0
     ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
     ; CHECK-NEXT: PseudoRET implicit $x10
@@ -133,7 +133,7 @@ body:             |
     %3:gpr = COPY $x13
     %4:gprnox0 = ADDIW %2, 0
     %5:gprnox0 = ADDIW %3, 0
-    %6:gprnox0 = PseudoCCMOVGPRNoX0 %0, %1, 1, %4, %5
+    %6:gprnox0 = PseudoCCMOVGPRNoX0 %4, %5, 1, %0, %1
     %7:gpr = ADDIW %6, 0
     $x10 = COPY %7
     PseudoRET implicit $x10
@@ -154,7 +154,7 @@ body:             |
     ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x13
     ; CHECK-NEXT: [[SRAIW:%[0-9]+]]:gprnox0 = SRAIW [[COPY2]], 0
     ; CHECK-NEXT: [[SRAIW1:%[0-9]+]]:gprnox0 = SRAIW [[COPY3]], 0
-    ; CHECK-NEXT: [[PseudoCCMOVGPRNoX0_:%[0-9]+]]:gprnox0 = PseudoCCMOVGPRNoX0 [[COPY]], [[COPY1]], 1, [[SRAIW]], [[SRAIW1]]
+    ; CHECK-NEXT: [[PseudoCCMOVGPRNoX0_:%[0-9]+]]:gprnox0 = PseudoCCMOVGPRNoX0 [[SRAIW]], [[SRAIW1]], 1, [[COPY]], [[COPY1]]
     ; CHECK-NEXT: $x10 = COPY [[PseudoCCMOVGPRNoX0_]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:gpr = COPY $x10
@@ -163,7 +163,7 @@ body:             |
     %3:gpr = COPY $x13
     %4:gprnox0 = SRAIW %2, 0
     %5:gprnox0 = SRAIW %3, 0
-    %6:gprnox0 = PseudoCCMOVGPRNoX0 %0, %1, 1, %4, %5
+    %6:gprnox0 = PseudoCCMOVGPRNoX0 %4, %5, 1, %0, %1
     %7:gpr = ADDIW %6, 0
     $x10 = COPY %7
     PseudoRET implicit $x10

>From 63f4815a74e2229820febae1479400a4123204db Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Mon, 2 Mar 2026 11:25:56 +0530
Subject: [PATCH 6/7] fixup! Address comments

Change-Id: Ib9c9f018a5898f3f561be54ffd7e4e03221f8aeb
---
 .../Target/RISCV/RISCVExpandPseudoInsts.cpp   | 19 +++++++------
 llvm/lib/Target/RISCV/RISCVInstrInfo.cpp      | 28 +++++++++++--------
 llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td |  8 +++---
 3 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index dee511525b479..ce6d2e2de9c96 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -216,12 +216,13 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
 
   // We want to copy the "true" value only when the branch is executed.
   // The SDNodeXform is responsible for the inversion.
-  unsigned BranchOpCode = MI.getOperand(MI.getNumOperands() - 3).getImm();
+  unsigned BranchOpCode =
+      MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
 
   // Insert branch instruction.
   BuildMI(MBB, MBBI, DL, TII->get(BranchOpCode))
-      .add(MI.getOperand(MI.getNumOperands() - 2))
-      .add(MI.getOperand(MI.getNumOperands() - 1))
+      .add(MI.getOperand(MI.getNumExplicitOperands() - 2))
+      .add(MI.getOperand(MI.getNumExplicitOperands() - 1))
       .addMBB(MergeBB);
 
   Register DestReg = MI.getOperand(0).getReg();
@@ -338,13 +339,13 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
     return false;
 
   // FIXME: Would be wonderful to support LHS=X0, but not very easy.
-  if (MI.getOperand(MI.getNumOperands() - 2).getReg() == RISCV::X0 ||
+  if (MI.getOperand(MI.getNumExplicitOperands() - 2).getReg() == RISCV::X0 ||
       MI.getOperand(1).getReg() == RISCV::X0 ||
       MI.getOperand(2).getReg() == RISCV::X0)
     return false;
 
   // Use branch opcode to select appropriate Xqcicm instruction
-  auto BCC = MI.getOperand(MI.getNumOperands() - 3).getImm();
+  unsigned BCC = MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
   unsigned CMovOpcode, CMovIOpcode;
   switch (BCC) {
   default:
@@ -375,7 +376,7 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
     break;
   }
 
-  if (MI.getOperand(MI.getNumOperands() - 1).getReg() == RISCV::X0) {
+  if (MI.getOperand(MI.getNumExplicitOperands() - 1).getReg() == RISCV::X0) {
     // $dst = PseudoCCMOVGPR $lhs, X0, $cc, $falsev (=$dst), $truev
     // $dst = PseudoCCMOVGPRNoX0 $lhs, X0, $cc, $falsev (=$dst), $truev
     // =>
@@ -383,7 +384,7 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
     BuildMI(MBB, MBBI, DL, TII->get(CMovIOpcode))
         .addDef(MI.getOperand(0).getReg())
         .addReg(MI.getOperand(1).getReg())
-        .addReg(MI.getOperand(MI.getNumOperands() - 2).getReg())
+        .addReg(MI.getOperand(MI.getNumExplicitOperands() - 2).getReg())
         .addImm(0)
         .addReg(MI.getOperand(2).getReg());
 
@@ -398,8 +399,8 @@ bool RISCVExpandPseudo::expandCCOpToCMov(MachineBasicBlock &MBB,
   BuildMI(MBB, MBBI, DL, TII->get(CMovOpcode))
       .addDef(MI.getOperand(0).getReg())
       .addReg(MI.getOperand(1).getReg())
-      .addReg(MI.getOperand(MI.getNumOperands() - 2).getReg())
-      .addReg(MI.getOperand(MI.getNumOperands() - 1).getReg())
+      .addReg(MI.getOperand(MI.getNumExplicitOperands() - 2).getReg())
+      .addReg(MI.getOperand(MI.getNumExplicitOperands() - 1).getReg())
       .addReg(MI.getOperand(2).getReg());
   MI.eraseFromParent();
   return true;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index fb0a551ea5567..99d2199997c7a 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -986,14 +986,14 @@ MachineInstr *RISCVInstrInfo::foldMemoryOperandImpl(
     NewMI.add(LoadMI.getOperand(i));
 
   // Add branch opcode, inverting if necessary.
-  auto BCC = MI.getOperand(MI.getNumOperands() - 3).getImm();
+  unsigned BCC = MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
   if (!Invert)
     BCC = RISCVCC::getInverseBranchOpcode(BCC);
   NewMI.addImm(BCC);
 
   // Copy condition portion
-  NewMI.add({MI.getOperand(MI.getNumOperands() - 2),
-             MI.getOperand(MI.getNumOperands() - 1)});
+  NewMI.add({MI.getOperand(MI.getNumExplicitOperands() - 2),
+             MI.getOperand(MI.getNumExplicitOperands() - 1)});
   NewMI.cloneMemRefs(LoadMI);
   return NewMI;
 }
@@ -2002,14 +2002,14 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI,
     NewMI.add(DefMI->getOperand(i));
 
   // Add branch opcode, inverting if necessary.
-  unsigned BCCOpcode = MI.getOperand(MI.getNumOperands() - 3).getImm();
+  unsigned BCCOpcode = MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
   if (Invert)
     BCCOpcode = RISCVCC::getInverseBranchOpcode(BCCOpcode);
   NewMI.addImm(BCCOpcode);
 
   // Copy the condition portion.
-  NewMI.add(MI.getOperand(MI.getNumOperands() - 2));
-  NewMI.add(MI.getOperand(MI.getNumOperands() - 1));
+  NewMI.add(MI.getOperand(MI.getNumExplicitOperands() - 2));
+  NewMI.add(MI.getOperand(MI.getNumExplicitOperands() - 1));
 
   // Update SeenMIs set: register newly created MI and erase removed DefMI.
   SeenMIs.insert(NewMI);
@@ -2067,7 +2067,9 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
     return STI.hasStdExtZca() ? 2 : 4;
   // Below cases are for short forward branch pseudos
   case RISCV::PseudoCCMOVGPRNoX0:
-    return get(MI.getOperand(MI.getNumOperands() - 3).getImm()).getSize() + 2;
+    return get(MI.getOperand(MI.getNumExplicitOperands() - 3).getImm())
+               .getSize() +
+           2;
   case RISCV::PseudoCCMOVGPR:
   case RISCV::PseudoCCADD:
   case RISCV::PseudoCCSUB:
@@ -2110,14 +2112,18 @@ unsigned RISCVInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
   case RISCV::PseudoCCLWU:
   case RISCV::PseudoCCLD:
   case RISCV::PseudoCCQC_LI:
-    return get(MI.getOperand(MI.getNumOperands() - 3).getImm()).getSize() + 4;
+    return get(MI.getOperand(MI.getNumExplicitOperands() - 3).getImm())
+               .getSize() +
+           4;
   case RISCV::PseudoCCQC_E_LI:
   case RISCV::PseudoCCQC_E_LB:
   case RISCV::PseudoCCQC_E_LH:
   case RISCV::PseudoCCQC_E_LW:
   case RISCV::PseudoCCQC_E_LHU:
   case RISCV::PseudoCCQC_E_LBU:
-    return get(MI.getOperand(MI.getNumOperands() - 3).getImm()).getSize() + 6;
+    return get(MI.getOperand(MI.getNumExplicitOperands() - 3).getImm())
+               .getSize() +
+           6;
   case TargetOpcode::STACKMAP:
     // The upper bound for a stackmap intrinsic is the full length of its shadow
     return StackMapOpers(&MI).getNumPatchBytes();
@@ -4377,10 +4383,10 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI,
   case RISCV::PseudoCCMOVGPRNoX0:
   case RISCV::PseudoCCMOVGPR: {
     // CCMOV can be commuted by inverting the condition.
-    auto BCC = MI.getOperand(MI.getNumOperands() - 3).getImm();
+    unsigned BCC = MI.getOperand(MI.getNumExplicitOperands() - 3).getImm();
     BCC = RISCVCC::getInverseBranchOpcode(BCC);
     auto &WorkingMI = cloneIfNew(MI);
-    WorkingMI.getOperand(MI.getNumOperands() - 3).setImm(BCC);
+    WorkingMI.getOperand(MI.getNumExplicitOperands() - 3).setImm(BCC);
     return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI*/ false,
                                                    OpIdx1, OpIdx2);
   }
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
index c4370bd9a9e89..00d1269b71360 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -937,10 +937,10 @@ defm : VPatTernaryVD4DOT_VV<"int_riscv_nds_vd4dotsu", "PseudoNDS_VD4DOTSU",
 
 class SFBNDS_BFO
     : Pseudo<(outs GPR:$dst),
-             (ins GPR:$lhs, sfb_rhs:$rhs, bcc_opcode:$bcc, GPR:$falsev, GPR:$rs1,
-                  uimmlog2xlen:$msb, uimmlog2xlen:$lsb), []>,
-      Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, ReadSFBALU,
-             ReadSFBALU]> {
+             (ins GPR:$falsev, GPR:$rs1, uimmlog2xlen:$msb, uimmlog2xlen:$lsb,
+                  bcc_opcode:$bcc, GPR:$lhs, sfb_rhs:$rhs), []>,
+      Sched<[WriteSFB, ReadSFBALU, ReadSFBALU,
+             ReadSFBALU, ReadSFBJmp, ReadSFBJmp]> {
   let hasSideEffects = 0;
   let mayLoad = 0;
   let mayStore = 0;

>From e1d109f8c657cacacf8b504083d44967fecd2f56 Mon Sep 17 00:00:00 2001
From: Harsh Chandel <hchandel at qti.qualcomm.com>
Date: Tue, 3 Mar 2026 11:17:50 +0530
Subject: [PATCH 7/7] fixup! Update comments

Change-Id: I5c4bbbfc5ed945086c9d5f275853520eb1df0d45
---
 llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
index 2cf8a46acaf2a..c02aa06c66c64 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoSFB.td
@@ -20,7 +20,7 @@ def sfb_rhs : RegisterOperand<GPR> {
   let OperandType = "OPERAND_SFB_RHS";
 }
 
-// cond -> bcc_opcode
+// cond -> bcc_opcode for reg, reg branches
 def CCtoRISCVBCC : SDNodeXForm<cond, [{
   ISD::CondCode CC = N->get();
   RISCVCC::CondCode RvCC = getRISCVCCForIntCC(CC);
@@ -174,7 +174,7 @@ def PseudoCCORN  : SFBALU_rr;
 def PseudoCCXNOR : SFBALU_rr;
 }
 
-// imm -> bcc_opcode
+// imm -> bcc_opcode for reg, reg  branches
 def RISCVCCtoRISCVBCC : SDNodeXForm<imm, [{
   auto CCImm = cast<ConstantSDNode>(N)->getZExtValue();
   auto RvCC = static_cast<RISCVCC::CondCode>(CCImm);



More information about the llvm-commits mailing list