[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