Skip to content

Commit bc2a5b5

Browse files
authored
[RISCV] Explicitly set FRM defs as non-dead to prevent their reordering with instructions that may use it (#135176)
Fixes #135172. The proposed solution is to conservatively reset dead flag from all $frm defs in AdjustInstrPostInstrSelection.
1 parent c58777c commit bc2a5b5

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20970,6 +20970,13 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
2097020970

2097120971
void RISCVTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
2097220972
SDNode *Node) const {
20973+
// If instruction defines FRM operand, conservatively set it as non-dead to
20974+
// express data dependency with FRM users and prevent incorrect instruction
20975+
// reordering.
20976+
if (auto *FRMDef = MI.findRegisterDefOperand(RISCV::FRM, /*TRI=*/nullptr)) {
20977+
FRMDef->setIsDead(false);
20978+
return;
20979+
}
2097320980
// Add FRM dependency to any instructions with dynamic rounding mode.
2097420981
int Idx = RISCV::getNamedOperandIdx(MI.getOpcode(), RISCV::OpName::frm);
2097520982
if (Idx < 0) {

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,9 +1941,11 @@ class SwapSysRegImm<SysReg SR, list<Register> Regs>
19411941
}
19421942

19431943
def ReadFRM : ReadSysReg<SysRegFRM, [FRM]>;
1944+
let hasPostISelHook = 1 in {
19441945
def WriteFRM : WriteSysReg<SysRegFRM, [FRM]>;
19451946
def WriteFRMImm : WriteSysRegImm<SysRegFRM, [FRM]>;
19461947
def SwapFRMImm : SwapSysRegImm<SysRegFRM, [FRM]>;
1948+
}
19471949

19481950
def WriteVXRMImm : WriteSysRegImm<SysRegVXRM, [VXRM]>;
19491951

llvm/test/CodeGen/RISCV/frm-write-in-loop.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ define double @foo(double %0, double %1, i64 %n) strictfp {
77
; CHECK-LABEL: foo:
88
; CHECK: # %bb.0: # %entry
99
; CHECK-NEXT: fmv.d.x fa5, zero
10-
; CHECK-NEXT: fsrmi 3
11-
; CHECK-NEXT: fsrmi 0
1210
; CHECK-NEXT: .LBB0_1: # %loop
1311
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
12+
; CHECK-NEXT: fsrmi 3
1413
; CHECK-NEXT: fadd.d fa5, fa5, fa0
1514
; CHECK-NEXT: addi a0, a0, -1
15+
; CHECK-NEXT: fsrmi 0
1616
; CHECK-NEXT: fadd.d fa5, fa5, fa1
1717
; CHECK-NEXT: beqz a0, .LBB0_1
1818
; CHECK-NEXT: # %bb.2: # %exit
@@ -53,12 +53,12 @@ define double @bar(double %0, double %1, i64 %n) strictfp {
5353
; CHECK-NEXT: fmv.d fs0, fa1
5454
; CHECK-NEXT: fmv.d fs1, fa0
5555
; CHECK-NEXT: fmv.d.x fa0, zero
56-
; CHECK-NEXT: fsrmi 3
57-
; CHECK-NEXT: fsrmi 0
5856
; CHECK-NEXT: .LBB1_1: # %loop
5957
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
58+
; CHECK-NEXT: fsrmi 3
6059
; CHECK-NEXT: fmv.d fa1, fs1
6160
; CHECK-NEXT: call baz
61+
; CHECK-NEXT: fsrmi 0
6262
; CHECK-NEXT: fmv.d fa1, fs0
6363
; CHECK-NEXT: call baz
6464
; CHECK-NEXT: addi s0, s0, -1

0 commit comments

Comments
 (0)