Skip to content

Commit a2e1de1

Browse files
committed
[ARM][FPEnv] Lowering of fpenv intrinsics
The change implements lowering of `get_fpenv`, `set_fpenv` and `reset_fpenv`. Differential Revision: https://reviews.llvm.org/D81843
1 parent 5923864 commit a2e1de1

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

llvm/include/llvm/Target/TargetSelectionDAG.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,9 @@ def strict_uint_to_fp : SDNode<"ISD::STRICT_UINT_TO_FP",
617617
def strict_fsetcc : SDNode<"ISD::STRICT_FSETCC", SDTSetCC, [SDNPHasChain]>;
618618
def strict_fsetccs : SDNode<"ISD::STRICT_FSETCCS", SDTSetCC, [SDNPHasChain]>;
619619

620+
def get_fpenv : SDNode<"ISD::GET_FPENV", SDTGetFPStateOp, [SDNPHasChain]>;
621+
def set_fpenv : SDNode<"ISD::SET_FPENV", SDTSetFPStateOp, [SDNPHasChain]>;
622+
def reset_fpenv : SDNode<"ISD::RESET_FPENV", SDTNone, [SDNPHasChain]>;
620623
def get_fpmode : SDNode<"ISD::GET_FPMODE", SDTGetFPStateOp, [SDNPHasChain]>;
621624
def set_fpmode : SDNode<"ISD::SET_FPMODE", SDTSetFPStateOp, [SDNPHasChain]>;
622625
def reset_fpmode : SDNode<"ISD::RESET_FPMODE", SDTNone, [SDNPHasChain]>;

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,9 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
14111411
setOperationAction(ISD::BITCAST, MVT::i64, Custom);
14121412
setOperationAction(ISD::GET_ROUNDING, MVT::i32, Custom);
14131413
setOperationAction(ISD::SET_ROUNDING, MVT::Other, Custom);
1414+
setOperationAction(ISD::GET_FPENV, MVT::i32, Legal);
1415+
setOperationAction(ISD::SET_FPENV, MVT::i32, Legal);
1416+
setOperationAction(ISD::RESET_FPENV, MVT::Other, Legal);
14141417
}
14151418

14161419
// We want to custom lower some of our intrinsics.

llvm/lib/Target/ARM/ARMInstrVFP.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2670,6 +2670,12 @@ def : Pat<(f32 (vfp_f32f16imm:$imm)),
26702670
let Predicates = [HasFullFP16];
26712671
}
26722672

2673+
// Floating-point environment management.
2674+
def : Pat<(get_fpenv), (VMRS)>;
2675+
def : Pat<(set_fpenv GPRnopc:$Rt), (VMSR GPRnopc:$Rt)>;
2676+
def : Pat<(reset_fpenv), (VMSR (MOVi 0))>, Requires<[IsARM]>;
2677+
def : Pat<(reset_fpenv), (VMSR (tMOVi8 0))>, Requires<[IsThumb]>;
2678+
26732679
//===----------------------------------------------------------------------===//
26742680
// Assembler aliases.
26752681
//

llvm/test/CodeGen/ARM/fpenv.ll

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2-
; RUN: llc -mtriple=arm-eabi -float-abi=soft -mattr=+vfp2 %s -o - | FileCheck %s
2+
; RUN: llc -mtriple=arm-eabi -float-abi=soft -mattr=+vfp2 --verify-machineinstrs %s -o - | FileCheck %s
33

44
define void @func_02(i32 %rm) {
55
; CHECK-LABEL: func_02:
@@ -79,6 +79,16 @@ entry:
7979
ret i32 %fpenv
8080
}
8181

82+
define i32 @get_fpenv_02() nounwind {
83+
; CHECK-LABEL: get_fpenv_02:
84+
; CHECK: @ %bb.0: @ %entry
85+
; CHECK-NEXT: vmrs r0, fpscr
86+
; CHECK-NEXT: mov pc, lr
87+
entry:
88+
%fpenv = call i32 @llvm.get.fpenv.i32()
89+
ret i32 %fpenv
90+
}
91+
8292
define void @set_fpenv_01(i32 %fpenv) #0 {
8393
; CHECK-LABEL: set_fpenv_01:
8494
; CHECK: @ %bb.0: @ %entry
@@ -97,6 +107,16 @@ entry:
97107
ret void
98108
}
99109

110+
define void @set_fpenv_02(i32 %fpenv) nounwind {
111+
; CHECK-LABEL: set_fpenv_02:
112+
; CHECK: @ %bb.0: @ %entry
113+
; CHECK-NEXT: vmsr fpscr, r0
114+
; CHECK-NEXT: mov pc, lr
115+
entry:
116+
call void @llvm.set.fpenv.i32(i32 %fpenv)
117+
ret void
118+
}
119+
100120
define void @reset_fpenv_01() #0 {
101121
; CHECK-LABEL: reset_fpenv_01:
102122
; CHECK: @ %bb.0: @ %entry
@@ -111,6 +131,17 @@ entry:
111131
ret void
112132
}
113133

134+
define void @reset_fpenv_02() nounwind {
135+
; CHECK-LABEL: reset_fpenv_02:
136+
; CHECK: @ %bb.0: @ %entry
137+
; CHECK-NEXT: mov r0, #0
138+
; CHECK-NEXT: vmsr fpscr, r0
139+
; CHECK-NEXT: mov pc, lr
140+
entry:
141+
call void @llvm.reset.fpenv()
142+
ret void
143+
}
144+
114145
attributes #0 = { nounwind "use-soft-float"="true" }
115146

116147
declare void @llvm.set.rounding(i32)

0 commit comments

Comments
 (0)