diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -3324,7 +3324,7 @@ double __builtin_canonicalize(double); float __builtin_canonicalizef(float); - long double__builtin_canonicalizel(long double); + long double __builtin_canonicalizel(long double); Returns the platform specific canonical encoding of a floating point number. This canonicalization is useful for implementing certain @@ -3332,6 +3332,28 @@ `_ for more information on the semantics. +``__builtin_flt_rounds`` and ``__builtin_set_flt_rounds`` +--------------------------------------------------------- + +.. code-block:: c + + int __builtin_flt_rounds(); + void __builtin_set_flt_rounds(int); + +Returns and sets current floating point rounding mode. The encoding of returned +values and input parameters is same as the result of FLT_ROUNDS, specified by C +standard: +- ``0`` - toward zero +- ``1`` - to nearest, ties to even +- ``2`` - toward positive infinity +- ``3`` - toward negative infinity +- ``4`` - to nearest, ties away from zero +The effect of passing some other value to ``__builtin_flt_rounds`` is +implementation-defined. ``__builtin_set_flt_rounds`` is currently only supported +to work on x86, x86_64, Arm and AArch64 targets. These builtins read and modify +the floating-point environment, which is not always allowed and may have unexpected +behavior. Please see the section on `Accessing the floating point environment `_ for more information. + String builtins --------------- diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1787,6 +1787,48 @@ * ``16`` - Forces ``_Float16`` operations to be emitted without using excess precision arithmetic. +.. _floating-point-environment: + +Accessing the floating point environment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Many targets allow floating point operations to be configured to control things +such as how inexact results should be rounded and how exceptional conditions +should be handled. This configuration is called the floating point environment. +C and C++ restrict access to the floating point environment by default, and the +compiler is allowed to assume that all operations are performed in the default +environment. When code is compiled in this default mode, operations that depend +on the environment (such as floating-point arithmetic and `FLT_ROUNDS`) may have +undefined behavior if the dynamic environment is not the default environment; for +example, `FLT_ROUNDS` may or may not simply return its default value for the target +instead of reading the dynamic environment, and floating-point operations may be +optimized as if the dynamic environment were the default. Similarly, it is undefined +behavior to change the floating point environment in this default mode, for example +by calling the `fesetround` function. +C provides two pragmas to allow code to dynamically modify the floating point environment: + +- ``#pragma STDC FENV_ACCESS ON`` allows dynamic changes to the entire floating + point environment. + +- ``#pragma STDC FENV_ROUND FE_DYNAMIC`` allows dynamic changes to just the floating + point rounding mode. This may be more optimizable than ``FENV_ACCESS ON`` because + the compiler can still ignore the possibility of floating-point exceptions by default. + +Both of these can be used either at the start of a block scope, in which case +they cover all code in that scope (unless they're turned off in a child scope), +or at the top level in a file, in which case they cover all subsequent function +bodies until they're turned off. Note that it is undefined behavior to enter +code that is *not* covered by one of these pragmas from code that *is* covered +by one of these pragmas unless the floating point environment has been restored +to its default state. See the C standard for more information about these pragmas. + +The command line option ``-frounding-math`` behaves as if the translation unit +began with ``#pragma STDC FENV_ROUND FE_DYNAMIC``. The command line option +``-ffp-model=strict`` behaves as if the translation unit began with ``#pragma STDC FENV_ACCESS ON``. + +Code that just wants to use a specific rounding mode for specific floating point +operations can avoid most of the hazards of the dynamic floating point environment +by using ``#pragma STDC FENV_ROUND`` with a value other than ``FE_DYNAMIC``. + .. _crtfastmath.o: A note about ``crtfastmath.o``