[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