This is an archive of the discontinued LLVM Phabricator instance.

[ARM][FPEnv] Lowering of {get,set,reset}_fpenv
ClosedPublic

Authored by sepavloff on Jun 15 2020, 8:04 AM.

Details

Summary

The change implements lowering of get_fpenv, set_fpenv and
reset_fpenv. The lowering is based on the intrinsic arm_get_fpscr.

Diff Detail

Event Timeline

sepavloff created this revision.Jun 15 2020, 8:04 AM
arsenm added a subscriber: arsenm.Jun 15 2020, 10:55 AM
arsenm added inline comments.
llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
273 ↗(On Diff #270750)

Addr.getValueType()

sepavloff updated this revision to Diff 272108.Jun 19 2020, 9:36 AM

Simplified address type calculation

sepavloff updated this revision to Diff 272366.Jun 22 2020, 3:01 AM
sepavloff marked an inline comment as done.

Updated patch as its dependency changed

sepavloff marked an inline comment as done.Jun 22 2020, 3:03 AM
sepavloff added inline comments.
llvm/lib/Target/ARM/ARMSelectionDAGInfo.cpp
273 ↗(On Diff #270750)

Fixed.

kpn added a subscriber: kpn.Jun 23 2020, 12:41 PM
sepavloff updated this revision to Diff 523051.May 17 2023, 7:41 AM

Update after update of dependency

Herald added a project: Restricted Project. · View Herald TranscriptMay 17 2023, 7:41 AM
john.brawn added inline comments.Oct 31 2023, 7:12 AM
llvm/lib/Target/ARM/ARMISelLowering.cpp
6449–6477

This could be done more simply by setting these nodes to Legal having tablegen patterns instead, e.g.

def : Pat<(get_fpenv), (VMRS)>;
def : Pat<(set_fpenv GPRnopc:$Rt), (VMSR GPRnopc:$Rt)>;
def : Pat<(reset_fpenv), (VMSR 0)>;

(though it requires get_fpenv etc. nodes being added to TargetSelectionDAG.td).

sepavloff updated this revision to Diff 558000.Nov 3 2023, 9:37 AM

Rebase and simplify implementation

sepavloff added inline comments.Nov 3 2023, 9:38 AM
llvm/lib/Target/ARM/ARMISelLowering.cpp
6449–6477

Indeed, this is much better.
Thank you!

This revision is now accepted and ready to land.Nov 7 2023, 2:17 AM
This revision was automatically updated to reflect the committed changes.

The patch was reverted because it caused fail on a buildbot with expensive checks. It detected that vmsr does not allow immediate as a source. I am going to modify this commit:

diff --git a/llvm/lib/Target/ARM/ARMInstrVFP.td b/llvm/lib/Target/ARM/ARMInstrVFP.td
index 7898972ee278..9b1224c7e1e3 100644
--- a/llvm/lib/Target/ARM/ARMInstrVFP.td
+++ b/llvm/lib/Target/ARM/ARMInstrVFP.td
@@ -2673,7 +2673,7 @@ def : Pat<(f32 (vfp_f32f16imm:$imm)),
 // Floating-point environment management.
 def : Pat<(get_fpenv), (VMRS)>;
 def : Pat<(set_fpenv GPRnopc:$Rt), (VMSR GPRnopc:$Rt)>;
-def : Pat<(reset_fpenv), (VMSR 0)>;
+def : Pat<(reset_fpenv), (VMSR (MOVi 0))>;
 
 //===----------------------------------------------------------------------===//
 // Assembler aliases.
diff --git a/llvm/test/CodeGen/ARM/fpenv.ll b/llvm/test/CodeGen/ARM/fpenv.ll
index f5c6a9608bac..40db627ebb3c 100644
--- a/llvm/test/CodeGen/ARM/fpenv.ll
+++ b/llvm/test/CodeGen/ARM/fpenv.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=arm-eabi -float-abi=soft -mattr=+vfp2 %s -o - | FileCheck %s
+; RUN: llc -mtriple=arm-eabi -float-abi=soft -mattr=+vfp2 --verify-machineinstrs %s -o - | FileCheck %s
 
 define void @func_02(i32 %rm) {
 ; CHECK-LABEL: func_02:
@@ -134,7 +134,8 @@ entry:
 define void @reset_fpenv_02() nounwind {
 ; CHECK-LABEL: reset_fpenv_02:
 ; CHECK:       @ %bb.0: @ %entry
-; CHECK-NEXT:    vmsr fpscr, #0
+; CHECK-NEXT:    mov r0, #0
+; CHECK-NEXT:    vmsr fpscr, r0
 ; CHECK-NEXT:    mov pc, lr
 entry:
   call void @llvm.reset.fpenv()

If there are no objections, I will commit the modified patch.

That would cause an invalid instruction to be emitted when compiling for thumb. I think you need one pattern using MOVi marked with Requires<[IsARM]>, and another using tMOVi8 marked with Requires<[IsThumb]>.

That would cause an invalid instruction to be emitted when compiling for thumb. I think you need one pattern using MOVi marked with Requires<[IsARM]>, and another using tMOVi8 marked with Requires<[IsThumb]>.

Thank you for advice! Now the problem place looks like:

--- a/llvm/lib/Target/ARM/ARMInstrVFP.td
+++ b/llvm/lib/Target/ARM/ARMInstrVFP.td
@@ -2673,7 +2673,8 @@ def : Pat<(f32 (vfp_f32f16imm:$imm)),
 // Floating-point environment management.
 def : Pat<(get_fpenv), (VMRS)>;
 def : Pat<(set_fpenv GPRnopc:$Rt), (VMSR GPRnopc:$Rt)>;
-def : Pat<(reset_fpenv), (VMSR 0)>;
+def : Pat<(reset_fpenv), (VMSR (MOVi 0))>, Requires<[IsARM]>;
+def : Pat<(reset_fpenv), (VMSR (tMOVi8 0))>, Requires<[IsThumb]>;