[llvm] [RISCV] Add hasSideEffects = true to ReadFRM (PR #139864)

Gergely Futo via llvm-commits llvm-commits at lists.llvm.org
Sat May 17 00:57:19 PDT 2025


https://github.com/futog updated https://github.com/llvm/llvm-project/pull/139864

>From a288cffe29afdac764b77f0f56bdd28f12ad957c Mon Sep 17 00:00:00 2001
From: Gergely Futo <gergely.futo at hightec-rt.com>
Date: Wed, 14 May 2025 16:33:57 +0200
Subject: [PATCH 1/2] [RISCV] [NFC] Add llvm.get.rounding test

Precommit for fixing ReadFRM.
---
 llvm/test/CodeGen/RISCV/fpenv.ll | 83 ++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/fpenv.ll b/llvm/test/CodeGen/RISCV/fpenv.ll
index 895effb4ce49b..d9da14bc6799d 100644
--- a/llvm/test/CodeGen/RISCV/fpenv.ll
+++ b/llvm/test/CodeGen/RISCV/fpenv.ll
@@ -26,6 +26,85 @@ define i32 @func_01() {
   ret i32 %rm
 }
 
+define i1 @test_get_rounding_sideeffect() #0 {
+; RV32IF-LABEL: test_get_rounding_sideeffect:
+; RV32IF:       # %bb.0: # %entry
+; RV32IF-NEXT:    addi sp, sp, -16
+; RV32IF-NEXT:    .cfi_def_cfa_offset 16
+; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
+; RV32IF-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
+; RV32IF-NEXT:    .cfi_offset ra, -4
+; RV32IF-NEXT:    .cfi_offset s0, -8
+; RV32IF-NEXT:    li a0, 1
+; RV32IF-NEXT:    call fesetround
+; RV32IF-NEXT:    frrm a0
+; RV32IF-NEXT:    lui a1, 66
+; RV32IF-NEXT:    slli a0, a0, 2
+; RV32IF-NEXT:    addi a1, a1, 769
+; RV32IF-NEXT:    srl s0, a1, a0
+; RV32IF-NEXT:    li a0, 0
+; RV32IF-NEXT:    andi s0, s0, 7
+; RV32IF-NEXT:    bnez s0, .LBB1_2
+; RV32IF-NEXT:  # %bb.1: # %if.end
+; RV32IF-NEXT:    call fesetround
+; RV32IF-NEXT:    addi s0, s0, -1
+; RV32IF-NEXT:    seqz a0, s0
+; RV32IF-NEXT:  .LBB1_2: # %return
+; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
+; RV32IF-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
+; RV32IF-NEXT:    .cfi_restore ra
+; RV32IF-NEXT:    .cfi_restore s0
+; RV32IF-NEXT:    addi sp, sp, 16
+; RV32IF-NEXT:    .cfi_def_cfa_offset 0
+; RV32IF-NEXT:    ret
+;
+; RV64IF-LABEL: test_get_rounding_sideeffect:
+; RV64IF:       # %bb.0: # %entry
+; RV64IF-NEXT:    addi sp, sp, -16
+; RV64IF-NEXT:    .cfi_def_cfa_offset 16
+; RV64IF-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
+; RV64IF-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
+; RV64IF-NEXT:    .cfi_offset ra, -8
+; RV64IF-NEXT:    .cfi_offset s0, -16
+; RV64IF-NEXT:    li a0, 1
+; RV64IF-NEXT:    call fesetround
+; RV64IF-NEXT:    frrm a0
+; RV64IF-NEXT:    lui a1, 66
+; RV64IF-NEXT:    slli a0, a0, 2
+; RV64IF-NEXT:    addiw a1, a1, 769
+; RV64IF-NEXT:    srl s0, a1, a0
+; RV64IF-NEXT:    li a0, 0
+; RV64IF-NEXT:    andi s0, s0, 7
+; RV64IF-NEXT:    bnez s0, .LBB1_2
+; RV64IF-NEXT:  # %bb.1: # %if.end
+; RV64IF-NEXT:    call fesetround
+; RV64IF-NEXT:    addi s0, s0, -1
+; RV64IF-NEXT:    seqz a0, s0
+; RV64IF-NEXT:  .LBB1_2: # %return
+; RV64IF-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
+; RV64IF-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
+; RV64IF-NEXT:    .cfi_restore ra
+; RV64IF-NEXT:    .cfi_restore s0
+; RV64IF-NEXT:    addi sp, sp, 16
+; RV64IF-NEXT:    .cfi_def_cfa_offset 0
+; RV64IF-NEXT:    ret
+entry:
+  %call = tail call i32 @fesetround(i32 noundef 1) #0
+  %0 = tail call i32 @llvm.get.rounding() #0
+  %cmp.not = icmp eq i32 %0, 0
+  br i1 %cmp.not, label %if.end, label %return
+
+if.end:
+  %call1 = tail call i32 @fesetround(i32 noundef 0) #0
+  %1 = tail call i32 @llvm.get.rounding() #0
+  %cmp2.not = icmp eq i32 %1, 1
+  br label %return
+
+return:
+  %retval.0 = phi i1 [ false, %entry ], [ %cmp2.not, %if.end ]
+  ret i1 %retval.0
+}
+
 define void @func_02(i32 %rm) {
 ; RV32IF-LABEL: func_02:
 ; RV32IF:       # %bb.0:
@@ -121,5 +200,9 @@ define void @func_07() {
   ret void
 }
 
+attributes #0 = { strictfp }
+
 declare void @llvm.set.rounding(i32)
 declare i32 @llvm.get.rounding()
+declare i32 @fesetround(i32 noundef)
+

>From 73b108940d2ffabf46d9df91c9be9ddc69f8bf9d Mon Sep 17 00:00:00 2001
From: Gergely Futo <gergely.futo at hightec-rt.com>
Date: Sat, 17 May 2025 09:37:43 +0200
Subject: [PATCH 2/2] [RISCV] Implement
 RISCVTargetLowering::getRoundingControlRegisters

By adding FRM/FFLAGS as implicit defs, ReadFRM is not optimized out.
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  5 +++
 llvm/lib/Target/RISCV/RISCVISelLowering.h   |  2 +
 llvm/test/CodeGen/RISCV/fpenv.ll            | 44 +++++++++++++--------
 3 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c01496c9a7f3a..585bf13cc6b04 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -24356,3 +24356,8 @@ RISCVTargetLowering::emitDynamicProbedAlloc(MachineInstr &MI,
   MF.getInfo<RISCVMachineFunctionInfo>()->setDynamicAllocation();
   return ExitMBB->begin()->getParent();
 }
+
+ArrayRef<MCPhysReg> RISCVTargetLowering::getRoundingControlRegisters() const {
+  static const MCPhysReg RCRegs[] = {RISCV::FRM, RISCV::FFLAGS};
+  return RCRegs;
+}
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index c865da80bcdf6..fc8d8b8ce1b56 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -450,6 +450,8 @@ class RISCVTargetLowering : public TargetLowering {
   MachineBasicBlock *emitDynamicProbedAlloc(MachineInstr &MI,
                                             MachineBasicBlock *MBB) const;
 
+  ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
+
 private:
   void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo,
                         const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,
diff --git a/llvm/test/CodeGen/RISCV/fpenv.ll b/llvm/test/CodeGen/RISCV/fpenv.ll
index d9da14bc6799d..11e104a290e1b 100644
--- a/llvm/test/CodeGen/RISCV/fpenv.ll
+++ b/llvm/test/CodeGen/RISCV/fpenv.ll
@@ -40,16 +40,22 @@ define i1 @test_get_rounding_sideeffect() #0 {
 ; RV32IF-NEXT:    frrm a0
 ; RV32IF-NEXT:    lui a1, 66
 ; RV32IF-NEXT:    slli a0, a0, 2
-; RV32IF-NEXT:    addi a1, a1, 769
-; RV32IF-NEXT:    srl s0, a1, a0
+; RV32IF-NEXT:    addi s0, a1, 769
+; RV32IF-NEXT:    srl a0, s0, a0
+; RV32IF-NEXT:    andi a0, a0, 7
+; RV32IF-NEXT:    beqz a0, .LBB1_2
+; RV32IF-NEXT:  # %bb.1:
 ; RV32IF-NEXT:    li a0, 0
-; RV32IF-NEXT:    andi s0, s0, 7
-; RV32IF-NEXT:    bnez s0, .LBB1_2
-; RV32IF-NEXT:  # %bb.1: # %if.end
+; RV32IF-NEXT:    j .LBB1_3
+; RV32IF-NEXT:  .LBB1_2: # %if.end
 ; RV32IF-NEXT:    call fesetround
-; RV32IF-NEXT:    addi s0, s0, -1
-; RV32IF-NEXT:    seqz a0, s0
-; RV32IF-NEXT:  .LBB1_2: # %return
+; RV32IF-NEXT:    frrm a0
+; RV32IF-NEXT:    slli a0, a0, 2
+; RV32IF-NEXT:    srl a0, s0, a0
+; RV32IF-NEXT:    andi a0, a0, 7
+; RV32IF-NEXT:    addi a0, a0, -1
+; RV32IF-NEXT:    seqz a0, a0
+; RV32IF-NEXT:  .LBB1_3: # %return
 ; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32IF-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
 ; RV32IF-NEXT:    .cfi_restore ra
@@ -71,16 +77,22 @@ define i1 @test_get_rounding_sideeffect() #0 {
 ; RV64IF-NEXT:    frrm a0
 ; RV64IF-NEXT:    lui a1, 66
 ; RV64IF-NEXT:    slli a0, a0, 2
-; RV64IF-NEXT:    addiw a1, a1, 769
-; RV64IF-NEXT:    srl s0, a1, a0
+; RV64IF-NEXT:    addiw s0, a1, 769
+; RV64IF-NEXT:    srl a0, s0, a0
+; RV64IF-NEXT:    andi a0, a0, 7
+; RV64IF-NEXT:    beqz a0, .LBB1_2
+; RV64IF-NEXT:  # %bb.1:
 ; RV64IF-NEXT:    li a0, 0
-; RV64IF-NEXT:    andi s0, s0, 7
-; RV64IF-NEXT:    bnez s0, .LBB1_2
-; RV64IF-NEXT:  # %bb.1: # %if.end
+; RV64IF-NEXT:    j .LBB1_3
+; RV64IF-NEXT:  .LBB1_2: # %if.end
 ; RV64IF-NEXT:    call fesetround
-; RV64IF-NEXT:    addi s0, s0, -1
-; RV64IF-NEXT:    seqz a0, s0
-; RV64IF-NEXT:  .LBB1_2: # %return
+; RV64IF-NEXT:    frrm a0
+; RV64IF-NEXT:    slli a0, a0, 2
+; RV64IF-NEXT:    srl a0, s0, a0
+; RV64IF-NEXT:    andi a0, a0, 7
+; RV64IF-NEXT:    addi a0, a0, -1
+; RV64IF-NEXT:    seqz a0, a0
+; RV64IF-NEXT:  .LBB1_3: # %return
 ; RV64IF-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IF-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
 ; RV64IF-NEXT:    .cfi_restore ra



More information about the llvm-commits mailing list