[llvm] [RISCV] Implement foward inserting save/restore FRM instructions. (PR #77744)

Yeting Kuo via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 17 22:10:10 PST 2024


================
@@ -55,6 +61,107 @@ char RISCVInsertReadWriteCSR::ID = 0;
 INITIALIZE_PASS(RISCVInsertReadWriteCSR, DEBUG_TYPE,
                 RISCV_INSERT_READ_WRITE_CSR_NAME, false, false)
 
+// TODO: Use more accurate rounding mode at the start of MBB.
+bool RISCVInsertReadWriteCSR::emitWriteRoundingModeOpt(MachineBasicBlock &MBB) {
+  bool Changed = false;
+  MachineInstr *LastFRMChanger = nullptr;
+  std::optional<unsigned> CurrentRM = RISCVFPRndMode::DYN;
+  std::optional<Register> SavedFRM;
+
+  for (MachineInstr &MI : MBB) {
+    if (MI.getOpcode() == RISCV::SwapFRMImm ||
+        MI.getOpcode() == RISCV::WriteFRMImm) {
+      CurrentRM = MI.getOperand(0).getImm();
+      SavedFRM = std::nullopt;
+      continue;
+    }
+
+    if (MI.getOpcode() == RISCV::WriteFRM) {
+      CurrentRM = RISCVFPRndMode::DYN;
+      SavedFRM = std::nullopt;
+      continue;
+    }
+
+    if (MI.isCall() || MI.isInlineAsm() || MI.readsRegister(RISCV::FRM)) {
+      // Restore FRM before unknown operations.
+      if (SavedFRM.has_value())
+        BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::WriteFRM))
+            .addReg(*SavedFRM);
+      CurrentRM = RISCVFPRndMode::DYN;
+      SavedFRM = std::nullopt;
+      continue;
+    }
+
+    assert(!MI.modifiesRegister(RISCV::FRM) &&
+           "Expected that MI could not modify FRM.");
+
+    auto getInstructionRM = [](MachineInstr &MI) -> std::optional<unsigned> {
+      int FRMIdx = RISCVII::getFRMOpNum(MI.getDesc());
+      if (FRMIdx >= 0)
+        return MI.getOperand(FRMIdx).getImm();
+
+      if (!MI.hasRegisterImplicitUseOperand(RISCV::FRM))
+        return std::nullopt;
+
+      return RISCVFPRndMode::DYN;
+    };
+
+    std::optional<unsigned> InstrRM = getInstructionRM(MI);
+
+    // Skip if MI does not need FRM.
+    if (!InstrRM.has_value())
+      continue;
+
+    if (InstrRM != RISCVFPRndMode::DYN)
+      LastFRMChanger = &MI;
+
+    if (!MI.readsRegister(RISCV::FRM))
----------------
yetingk wrote:

It's needed now since vector rounding pseudo instructions don't implicit uses `FRM`. 

https://github.com/llvm/llvm-project/pull/77744


More information about the llvm-commits mailing list