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