[llvm] [RISCV] Explicitly set FRM defs as non-dead to prevent their reordering with instructions that may use it (PR #135176)

Sergey Kachkov via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 11 02:49:25 PDT 2025


https://github.com/skachkov-sc updated https://github.com/llvm/llvm-project/pull/135176

>From eeb7e25e44c8b2542fe5031049cbf1e27b998c45 Mon Sep 17 00:00:00 2001
From: Sergey Kachkov <sergey.kachkov at syntacore.com>
Date: Thu, 10 Apr 2025 12:48:08 +0300
Subject: [PATCH] [RISCV] Explicitly set FRM defs as non-dead to prevent their
 reordering with instructions that may use it

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp  | 7 +++++++
 llvm/lib/Target/RISCV/RISCVInstrInfo.td      | 2 ++
 llvm/test/CodeGen/RISCV/frm-write-in-loop.ll | 8 ++++----
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index fd0562d141796..fef9084bd0e73 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20970,6 +20970,13 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
 
 void RISCVTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
                                                         SDNode *Node) const {
+  // If instruction defines FRM operand, conservatively set it as non-dead to
+  // express data dependency with FRM users and prevent incorrect instruction
+  // reordering.
+  if (auto *FRMDef = MI.findRegisterDefOperand(RISCV::FRM, /*TRI=*/nullptr)) {
+    FRMDef->setIsDead(false);
+    return;
+  }
   // Add FRM dependency to any instructions with dynamic rounding mode.
   int Idx = RISCV::getNamedOperandIdx(MI.getOpcode(), RISCV::OpName::frm);
   if (Idx < 0) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index c87452171f090..1104d9089536f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1941,9 +1941,11 @@ class SwapSysRegImm<SysReg SR, list<Register> Regs>
 }
 
 def ReadFRM : ReadSysReg<SysRegFRM, [FRM]>;
+let hasPostISelHook = 1 in {
 def WriteFRM : WriteSysReg<SysRegFRM, [FRM]>;
 def WriteFRMImm : WriteSysRegImm<SysRegFRM, [FRM]>;
 def SwapFRMImm : SwapSysRegImm<SysRegFRM, [FRM]>;
+}
 
 def WriteVXRMImm : WriteSysRegImm<SysRegVXRM, [VXRM]>;
 
diff --git a/llvm/test/CodeGen/RISCV/frm-write-in-loop.ll b/llvm/test/CodeGen/RISCV/frm-write-in-loop.ll
index 55a45b8f16323..4f435067343b7 100644
--- a/llvm/test/CodeGen/RISCV/frm-write-in-loop.ll
+++ b/llvm/test/CodeGen/RISCV/frm-write-in-loop.ll
@@ -7,12 +7,12 @@ define double @foo(double %0, double %1, i64 %n) strictfp {
 ; CHECK-LABEL: foo:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    fmv.d.x fa5, zero
-; CHECK-NEXT:    fsrmi 3
-; CHECK-NEXT:    fsrmi 0
 ; CHECK-NEXT:  .LBB0_1: # %loop
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    fsrmi 3
 ; CHECK-NEXT:    fadd.d fa5, fa5, fa0
 ; CHECK-NEXT:    addi a0, a0, -1
+; CHECK-NEXT:    fsrmi 0
 ; CHECK-NEXT:    fadd.d fa5, fa5, fa1
 ; CHECK-NEXT:    beqz a0, .LBB0_1
 ; CHECK-NEXT:  # %bb.2: # %exit
@@ -53,12 +53,12 @@ define double @bar(double %0, double %1, i64 %n) strictfp {
 ; CHECK-NEXT:    fmv.d fs0, fa1
 ; CHECK-NEXT:    fmv.d fs1, fa0
 ; CHECK-NEXT:    fmv.d.x fa0, zero
-; CHECK-NEXT:    fsrmi 3
-; CHECK-NEXT:    fsrmi 0
 ; CHECK-NEXT:  .LBB1_1: # %loop
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    fsrmi 3
 ; CHECK-NEXT:    fmv.d fa1, fs1
 ; CHECK-NEXT:    call baz
+; CHECK-NEXT:    fsrmi 0
 ; CHECK-NEXT:    fmv.d fa1, fs0
 ; CHECK-NEXT:    call baz
 ; CHECK-NEXT:    addi s0, s0, -1



More information about the llvm-commits mailing list