@@ -1446,6 +1446,127 @@ RISCVInstrInfo::optimizeSelect(MachineInstr &MI,
14461446 return NewMI;
14471447}
14481448
1449+ int RISCVInstrInfo::getICmpCost (unsigned CC,
1450+ const TargetSchedModel &SchedModel) const {
1451+ switch (CC) {
1452+ default :
1453+ llvm_unreachable (" Unknown condition code!" );
1454+ case RISCVCC::COND_LT:
1455+ return SchedModel.computeInstrLatency (RISCV::SLT);
1456+ case RISCVCC::COND_LTU:
1457+ return SchedModel.computeInstrLatency (RISCV::SLTU);
1458+ case RISCVCC::COND_EQ:
1459+ return SchedModel.computeInstrLatency (RISCV::XOR) +
1460+ SchedModel.computeInstrLatency (RISCV::SLTIU);
1461+ case RISCVCC::COND_NE:
1462+ return SchedModel.computeInstrLatency (RISCV::XOR) +
1463+ SchedModel.computeInstrLatency (RISCV::SLTU);
1464+ case RISCVCC::COND_GE:
1465+ return SchedModel.computeInstrLatency (RISCV::XORI) +
1466+ SchedModel.computeInstrLatency (RISCV::SLT);
1467+ case RISCVCC::COND_GEU:
1468+ return SchedModel.computeInstrLatency (RISCV::XORI) +
1469+ SchedModel.computeInstrLatency (RISCV::SLTU);
1470+ }
1471+ }
1472+
1473+ void RISCVInstrInfo::insertICmp (MachineBasicBlock &MBB,
1474+ MachineBasicBlock::iterator MI,
1475+ const DebugLoc &DL, Register DstReg,
1476+ ArrayRef<MachineOperand> Cond) const {
1477+ MachineRegisterInfo &MRI = MI->getParent ()->getParent ()->getRegInfo ();
1478+ unsigned CC = Cond[0 ].getImm ();
1479+ Register LHSReg = Cond[1 ].getReg ();
1480+ Register RHSReg = Cond[2 ].getReg ();
1481+
1482+ switch (CC) {
1483+ default :
1484+ llvm_unreachable (" Unknown condition code!" );
1485+ case RISCVCC::COND_LT:
1486+ case RISCVCC::COND_LTU: {
1487+ BuildMI (MBB, MI, DL, get (CC == RISCVCC::COND_LT ? RISCV::SLT : RISCV::SLTU),
1488+ DstReg)
1489+ .addReg (LHSReg)
1490+ .addReg (RHSReg);
1491+ return ;
1492+ }
1493+ case RISCVCC::COND_EQ:
1494+ case RISCVCC::COND_NE: {
1495+ Register XorReg = MRI.createVirtualRegister (&RISCV::GPRRegClass);
1496+ BuildMI (MBB, MI, DL, get (RISCV::XOR), XorReg).addReg (LHSReg).addReg (RHSReg);
1497+ if (CC == RISCVCC::COND_EQ) {
1498+ BuildMI (MBB, MI, DL, get (RISCV::SLTIU), DstReg).addReg (XorReg).addImm (1 );
1499+ return ;
1500+ } else {
1501+ BuildMI (MBB, MI, DL, get (RISCV::SLTU), DstReg)
1502+ .addReg (RISCV::X0)
1503+ .addReg (XorReg);
1504+ return ;
1505+ }
1506+ }
1507+ case RISCVCC::COND_GE:
1508+ case RISCVCC::COND_GEU: {
1509+ Register NotCCReg = MRI.createVirtualRegister (&RISCV::GPRRegClass);
1510+ BuildMI (MBB, MI, DL, get (CC == RISCVCC::COND_GE ? RISCV::SLT : RISCV::SLTU),
1511+ NotCCReg)
1512+ .addReg (LHSReg)
1513+ .addReg (RHSReg);
1514+ BuildMI (MBB, MI, DL, get (RISCV::XORI), DstReg).addReg (NotCCReg).addImm (1 );
1515+ return ;
1516+ }
1517+ }
1518+ }
1519+
1520+ void RISCVInstrInfo::insertSelect (MachineBasicBlock &MBB,
1521+ MachineBasicBlock::iterator MI,
1522+ const DebugLoc &DL, Register DstReg,
1523+ ArrayRef<MachineOperand> Cond,
1524+ Register TrueReg, Register FalseReg) const {
1525+ MachineFunction &MF = *MI->getParent ()->getParent ();
1526+ const RISCVSubtarget &ST = MF.getSubtarget <RISCVSubtarget>();
1527+ MachineRegisterInfo &MRI = MF.getRegInfo ();
1528+
1529+ Register CCReg = MRI.createVirtualRegister (&RISCV::GPRRegClass);
1530+ insertICmp (MBB, MI, DL, CCReg, Cond);
1531+ unsigned CondZeroEqzOpc =
1532+ ST.hasVendorXVentanaCondOps () ? RISCV::VT_MASKC : RISCV::CZERO_EQZ;
1533+ unsigned CondZeroNezOpc =
1534+ ST.hasVendorXVentanaCondOps () ? RISCV::VT_MASKCN : RISCV::CZERO_NEZ;
1535+ Register TrueValOrZeroReg = MRI.createVirtualRegister (&RISCV::GPRRegClass);
1536+ Register FalseValOrZeroReg = MRI.createVirtualRegister (&RISCV::GPRRegClass);
1537+ BuildMI (MBB, MI, DL, get (CondZeroEqzOpc), TrueValOrZeroReg)
1538+ .addReg (TrueReg)
1539+ .addReg (CCReg);
1540+ BuildMI (MBB, MI, DL, get (CondZeroNezOpc), FalseValOrZeroReg)
1541+ .addReg (FalseReg)
1542+ .addReg (CCReg);
1543+ BuildMI (MBB, MI, DL, get (RISCV::OR), DstReg)
1544+ .addReg (TrueValOrZeroReg)
1545+ .addReg (FalseValOrZeroReg);
1546+ return ;
1547+ }
1548+
1549+ bool RISCVInstrInfo::canInsertSelect (const MachineBasicBlock &MBB,
1550+ ArrayRef<MachineOperand> Cond,
1551+ Register DstReg, Register TrueReg,
1552+ Register FalseReg, int &CondCycles,
1553+ int &TrueCycles, int &FalseCycles) const {
1554+ TargetSchedModel SchedModel;
1555+ SchedModel.init (&STI);
1556+
1557+ CondCycles = getICmpCost (Cond[0 ].getImm (), SchedModel);
1558+ TrueCycles = SchedModel.computeInstrLatency (RISCV::OR) +
1559+ SchedModel.computeInstrLatency (STI.hasVendorXVentanaCondOps ()
1560+ ? RISCV::VT_MASKC
1561+ : RISCV::CZERO_EQZ);
1562+ FalseCycles = SchedModel.computeInstrLatency (RISCV::OR) +
1563+ SchedModel.computeInstrLatency (STI.hasVendorXVentanaCondOps ()
1564+ ? RISCV::VT_MASKCN
1565+ : RISCV::CZERO_NEZ);
1566+
1567+ return true ;
1568+ }
1569+
14491570unsigned RISCVInstrInfo::getInstSizeInBytes (const MachineInstr &MI) const {
14501571 if (MI.isMetaInstruction ())
14511572 return 0 ;
0 commit comments