[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