Skip to content

Commit

Permalink
[ARM][FPEnv] Lowering of fpenv intrinsics
Browse files Browse the repository at this point in the history
The change implements lowering of `get_fpenv`, `set_fpenv` and
`reset_fpenv`.

Differential Revision: https://reviews.llvm.org/D81843
  • Loading branch information
spavloff committed Nov 10, 2023
1 parent d451721 commit d62f040
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 0 deletions.
3 changes: 3 additions & 0 deletions llvm/include/llvm/Target/TargetSelectionDAG.td
Expand Up @@ -617,6 +617,9 @@ def strict_uint_to_fp : SDNode<"ISD::STRICT_UINT_TO_FP",
def strict_fsetcc : SDNode<"ISD::STRICT_FSETCC", SDTSetCC, [SDNPHasChain]>;
def strict_fsetccs : SDNode<"ISD::STRICT_FSETCCS", SDTSetCC, [SDNPHasChain]>;

def get_fpenv : SDNode<"ISD::GET_FPENV", SDTGetFPStateOp, [SDNPHasChain]>;
def set_fpenv : SDNode<"ISD::SET_FPENV", SDTSetFPStateOp, [SDNPHasChain]>;
def reset_fpenv : SDNode<"ISD::RESET_FPENV", SDTNone, [SDNPHasChain]>;
def get_fpmode : SDNode<"ISD::GET_FPMODE", SDTGetFPStateOp, [SDNPHasChain]>;
def set_fpmode : SDNode<"ISD::SET_FPMODE", SDTSetFPStateOp, [SDNPHasChain]>;
def reset_fpmode : SDNode<"ISD::RESET_FPMODE", SDTNone, [SDNPHasChain]>;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Expand Up @@ -1411,6 +1411,9 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::BITCAST, MVT::i64, Custom);
setOperationAction(ISD::GET_ROUNDING, MVT::i32, Custom);
setOperationAction(ISD::SET_ROUNDING, MVT::Other, Custom);
setOperationAction(ISD::GET_FPENV, MVT::i32, Legal);
setOperationAction(ISD::SET_FPENV, MVT::i32, Legal);
setOperationAction(ISD::RESET_FPENV, MVT::Other, Legal);
}

// We want to custom lower some of our intrinsics.
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/ARM/ARMInstrVFP.td
Expand Up @@ -2670,6 +2670,11 @@ def : Pat<(f32 (vfp_f32f16imm:$imm)),
let Predicates = [HasFullFP16];
}

// Floating-point environment management.
def : Pat<(get_fpenv), (VMRS)>;
def : Pat<(set_fpenv GPRnopc:$Rt), (VMSR GPRnopc:$Rt)>;
def : Pat<(reset_fpenv), (VMSR 0)>;

//===----------------------------------------------------------------------===//
// Assembler aliases.
//
Expand Down
30 changes: 30 additions & 0 deletions llvm/test/CodeGen/ARM/fpenv.ll
Expand Up @@ -79,6 +79,16 @@ entry:
ret i32 %fpenv
}

define i32 @get_fpenv_02() nounwind {
; CHECK-LABEL: get_fpenv_02:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: vmrs r0, fpscr
; CHECK-NEXT: mov pc, lr
entry:
%fpenv = call i32 @llvm.get.fpenv.i32()
ret i32 %fpenv
}

define void @set_fpenv_01(i32 %fpenv) #0 {
; CHECK-LABEL: set_fpenv_01:
; CHECK: @ %bb.0: @ %entry
Expand All @@ -97,6 +107,16 @@ entry:
ret void
}

define void @set_fpenv_02(i32 %fpenv) nounwind {
; CHECK-LABEL: set_fpenv_02:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: vmsr fpscr, r0
; CHECK-NEXT: mov pc, lr
entry:
call void @llvm.set.fpenv.i32(i32 %fpenv)
ret void
}

define void @reset_fpenv_01() #0 {
; CHECK-LABEL: reset_fpenv_01:
; CHECK: @ %bb.0: @ %entry
Expand All @@ -111,6 +131,16 @@ entry:
ret void
}

define void @reset_fpenv_02() nounwind {
; CHECK-LABEL: reset_fpenv_02:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: vmsr fpscr, #0
; CHECK-NEXT: mov pc, lr
entry:
call void @llvm.reset.fpenv()
ret void
}

attributes #0 = { nounwind "use-soft-float"="true" }

declare void @llvm.set.rounding(i32)
Expand Down

0 comments on commit d62f040

Please sign in to comment.