The change introduces intrinsics 'get_fpmode', 'set_fpmode' and
'reset_fpmode'. They manage all target dynamic floating-point control
modes, which include, for instance, rounding direction, precision,
treatment of denormals and so on. The intrinsics do the same
operations as the C library functions 'fegetmode' and 'fesetmode'. By
default they are lowered to calls to these functions.
Two main use cases are supported by this implementation.
- Local modification of the control modes. In this case the code
usually has a pattern (in pseudocode):
saved_modes = get_fpmode() set_fpmode(<new_modes>) ... <do operations with new modes> ... set_fpmode(saved_modes)
In the case when it is known that the current FP environment is default,
the code may be shorter:
set_fpmode(<new_modes>) ... <do operations with new modes> ... reset_fpmode()
Such patterns appear not only in user code but also in implementations
of various FP controlling pragmas. In particular, the implementation of
#pragma STDC FENV_ROUND requires similar code if the target does not
support static rounding mode.
- Portable control of FP modes. Usually FP control modes are set by
write to some control register. Different targets have different
layout of this register, the way the register is accessed also may be
different. Using set of target-specific definitions for the control
register bits together with these intrinsic functions provides enough
portable way to handle control modes across wide range of hardware.
This change defines only llvm intrinsic function, which implement the
access required for the aforementioned use cases.
clang-tidy: warning: invalid case style for function 'CreateGetFPMode' [readability-identifier-naming]
not useful