Hi all,
Implementation of #pragma STDC FENV_ACCESS raises a problem: what to do if a function is called inside a region where FP environment differs from the default? If the function expects default FP mode it may work incorrectly in such case.
The C2x standard draft (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2454.pdf) states (7.6p4):
Certain programming conventions support the intended model of use for the dynamic floating-point environment:*)
— a function call does not alter its caller’s floating-point control modes, clear its caller’s floating point status flags, nor depend on the state of its caller’s floating-point status flags unless the function is so documented;
— a function call is assumed to require default floating-point control modes, unless its documentation promises otherwise;
— a function call is assumed to have the potential for raising floating-point exceptions, unless its documentation promises otherwise.
*) With these conventions, a programmer can safely assume default floating-point control modes (or be unaware of them). The responsibilities associated with accessing the floating-point environment fall on the programmer or program that does so explicitly.
It looks like that the standard requires to call functions in default FP mode, so inside a block where #pragma STDC FENV_ACCESS acts, each function call should be converted into sequence:
- store FP state,
- set default FP state,
- call the function,
- restore FP state.
These save/restore instructions could be inserted by compiler. This could be the safest solution but it complicates implementation and may impact performance. There is also another viewpoint: it is user responsibility to provide necessary environment and save/restore operations must be inserted manually.
Choosing the proper way we need to take into account:
- generally it is hard for a user to be sure that a function do not depend on FP environment. Functions that apparently do not use FP numbers (like addition to hash table) may actually involve FP operations internally.
- function inlining occurs in IR level and the chosen solution may potentially affect semantics of other languages (maybe Fortran?).
So the first question is: should the compiler set default FP state prior to function calls?
The next question is: should the compiler support some frontend attribute to mark functions that do not require default FP mode? These are functions that:
- do not involve FP operations,
- work correctly in any FP mode,
- expects particular FP mode,
- modifies FP mode,
- probably something else.
For such functions compiler would not generate save/restore operations. We also could have several attributes if we need to distinguish between these cases.