[llvm] [RISCV] Enable early if-conversion (PR #92959)
Mikhail Gudim via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 26 20:39:39 PDT 2024
================
@@ -1446,6 +1446,196 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI,
return NewMI;
}
+int RISCVInstrInfo::getICmpCost(unsigned CC,
+ const TargetSchedModel &SchedModel) const {
+ switch (CC) {
+ default:
+ llvm_unreachable("Unknown condition code!");
+ case RISCVCC::COND_LT:
+ return SchedModel.computeInstrLatency(RISCV::SLT);
+ case RISCVCC::COND_LTU:
+ return SchedModel.computeInstrLatency(RISCV::SLTU);
+ case RISCVCC::COND_EQ:
+ return SchedModel.computeInstrLatency(RISCV::XOR) +
+ SchedModel.computeInstrLatency(RISCV::SLTIU);
+ case RISCVCC::COND_NE:
+ return SchedModel.computeInstrLatency(RISCV::XOR) +
+ SchedModel.computeInstrLatency(RISCV::SLTU);
+ case RISCVCC::COND_GE:
+ return SchedModel.computeInstrLatency(RISCV::XORI) +
+ SchedModel.computeInstrLatency(RISCV::SLT);
+ case RISCVCC::COND_GEU:
+ return SchedModel.computeInstrLatency(RISCV::XORI) +
+ SchedModel.computeInstrLatency(RISCV::SLTU);
+ }
+}
+
+void RISCVInstrInfo::insertICmp(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const DebugLoc &DL, Register DstReg,
+ unsigned CC, Register LHSReg,
+ Register RHSReg) const {
+ MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
+
+ switch (CC) {
+ default:
+ llvm_unreachable("Unknown condition code!");
+ case RISCVCC::COND_LT:
+ case RISCVCC::COND_LTU: {
+ BuildMI(MBB, MI, DL, get(CC == RISCVCC::COND_LT ? RISCV::SLT : RISCV::SLTU),
+ DstReg)
+ .addReg(LHSReg)
+ .addReg(RHSReg);
+ return;
+ }
+ case RISCVCC::COND_EQ:
+ case RISCVCC::COND_NE: {
+ Register XorReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ BuildMI(MBB, MI, DL, get(RISCV::XOR), XorReg).addReg(LHSReg).addReg(RHSReg);
+ if (CC == RISCVCC::COND_EQ) {
+ BuildMI(MBB, MI, DL, get(RISCV::SLTIU), DstReg).addReg(XorReg).addImm(1);
+ return;
+ } else {
+ BuildMI(MBB, MI, DL, get(RISCV::SLTU), DstReg)
+ .addReg(RISCV::X0)
+ .addReg(XorReg);
+ return;
+ }
+ }
+ case RISCVCC::COND_GE:
+ case RISCVCC::COND_GEU: {
+ Register NotCCReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ BuildMI(MBB, MI, DL, get(CC == RISCVCC::COND_GE ? RISCV::SLT : RISCV::SLTU),
+ NotCCReg)
+ .addReg(LHSReg)
+ .addReg(RHSReg);
+ BuildMI(MBB, MI, DL, get(RISCV::XORI), DstReg).addReg(NotCCReg).addImm(1);
+ return;
+ }
+ }
+}
+
+void RISCVInstrInfo::insertSelect(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const DebugLoc &DL, Register DstReg,
+ ArrayRef<MachineOperand> Cond,
+ Register TrueReg, Register FalseReg) const {
+ MachineFunction &MF = *MI->getParent()->getParent();
+ const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
+ const TargetRegisterInfo &TRI = *ST.getRegisterInfo();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ Register CCReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+
+ unsigned CC = Cond[0].getImm();
+ Register LHSReg = Cond[1].getReg();
+ Register RHSReg = Cond[2].getReg();
+
+ unsigned CondZeroEqzOpc =
+ ST.hasVendorXVentanaCondOps() ? RISCV::VT_MASKC : RISCV::CZERO_EQZ;
+ unsigned CondZeroNezOpc =
+ ST.hasVendorXVentanaCondOps() ? RISCV::VT_MASKCN : RISCV::CZERO_NEZ;
+
+ const TargetRegisterClass *DstRC = MRI.getRegClass(DstReg);
+ const TargetRegisterClass *CommonRC =
+ TRI.getCommonSubClass(DstRC, &RISCV::GPRRegClass);
+ bool NeedsRCCopies = (CommonRC != DstRC) && (CommonRC != &RISCV::GPRRegClass);
+
+ Register CondZeroEqzReg = TrueReg;
+ Register CondZeroNezReg = FalseReg;
+ if (NeedsRCCopies) {
+ CondZeroEqzReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ BuildMI(MBB, MI, DL, get(TargetOpcode::COPY), CondZeroEqzReg)
+ .addReg(TrueReg);
+ CondZeroNezReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ BuildMI(MBB, MI, DL, get(TargetOpcode::COPY), CondZeroNezReg)
+ .addReg(FalseReg);
+ }
+ if (CC == RISCVCC::COND_GE || CC == RISCVCC::COND_GEU) {
+ CC = (CC == RISCVCC::COND_GE) ? RISCVCC::COND_LT : RISCVCC::COND_LTU;
+ std::swap(CondZeroEqzReg, CondZeroNezReg);
+ }
+ insertICmp(MBB, MI, DL, CCReg, CC, LHSReg, RHSReg);
+
+ Register TrueValOrZeroReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ Register FalseValOrZeroReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ BuildMI(MBB, MI, DL, get(CondZeroEqzOpc), TrueValOrZeroReg)
----------------
mgudim wrote:
This needs to be merged first: https://github.com/llvm/llvm-project/pull/95877
This MR uses a hack to bypass that.
Also I need to add some tests too.
https://github.com/llvm/llvm-project/pull/92959
More information about the llvm-commits
mailing list