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 Regs> } def ReadFRM : ReadSysReg; +let hasPostISelHook = 1 in { def WriteFRM : WriteSysReg; def WriteFRMImm : WriteSysRegImm; def SwapFRMImm : SwapSysRegImm; +} def WriteVXRMImm : WriteSysRegImm; 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