rjmccall added a comment.

In D69272#1865266 <https://reviews.llvm.org/D69272#1865266>, @rsmith wrote:

> I don't see any changes to the constant evaluator here. You need to properly 
> handle constant evaluation within `FENV_ACCESS ON` contexts, somehow, or 
> you'll miscompile floating-point operations with constant operands. Probably 
> the easiest thing would be to treat all rounded FP operations as non-constant 
> in an `FENV_ACCESS ON` region, though in C++ `constexpr` evaluations we could 
> permit rounded FP operations if the evaluation began in an `FENV_ACCESS OFF` 
> region (that way we know the computations should be done in the default FP 
> environment because `feset*` are not `constexpr` functions).


FWIW, C does actually specify behavior here:

> C2x (n2454)
>  **F.8.4 Constant expressions**
>  p1. An arithmetic constant expression of floating type, other than one in an 
> initializer for an object that has static or thread storage duration, is 
> evaluated (as if) during execution; thus, it is affected by any operative 
> floating-point control modes and raises floating-point exceptions as required 
> by IEC 60559 (provided the state for the FENV_ACCESS pragma is "on").
> 
> p2. Example:
> 
>   #include <fenv.h>
>   #pragma STDC FENV_ACCESS ON
>   void f(void)
>   {
>     float w[] = { 0.0/0.0 };  // raises an exception
>     static float x = 0.0/0.0; // does not raise an exception
>     float y = 0.0/0.0;        // raises an exception
>     double z = 0.0/0.0;       // raises an exception
>     /* ... */
>   }
> 
> 
> p3. For the static initialization, the division is done at translation time, 
> raising no (execution-time) floating-point exceptions. On the other hand, for 
> the three automatic initializations the invalid division occurs at execution 
> time.
> 
> **F.8.2 Translation**
>  p1. During translation, constant rounding direction modes are in effect 
> where specified. Elsewhere, during translation the IEC 60559 default modes 
> are in effect:
> 
> - The rounding direction mode is rounding to nearest.
> - The rounding precision mode (if supported) is set so that results are not 
> shortened.
> - Trapping or stopping (if supported) is disabled on all floating-point 
> exceptions.
> 
>   p2. (Recommended practice) The implementation should produce a diagnostic 
> message for each translation-time floating-point exception, other than 
> "inexact"; the implementation should then proceed with the translation of the 
> program.

Some of this translates naturally to C++: e.g. `constexpr` evaluations are 
always "during translation" and therefore should honor rounding modes but not 
the dynamic environment.  Of course, C++ also allows static initialization to 
be non-constant, and we don't really want an implementation decision (or the 
presence of one perhaps-unexpectedly non-constexpr sub-expression) to cause 
gross differences in behavior.  I think the most consistent rule is to say that 
`FENV_ACCESS` just doesn't apply to the direct initializers of file-scope 
variables and static data members, so if you want static initialization to be 
environment-aware, you need to move it into a function with the pragma active, 
which then (as you suggest) cannot be constant-folded.  I guess `FENV_ACCESS` 
*would* apply to the initialization of static local variable unless it was 
`constinit`, which would be a C vs. C++ inconsistency but hopefully an 
understandable one.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69272/new/

https://reviews.llvm.org/D69272



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D69272: E... Serge Pavlov via Phabricator via cfe-commits
    • [PATCH] D692... John McCall via Phabricator via cfe-commits
    • [PATCH] D692... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D692... John McCall via Phabricator via cfe-commits

Reply via email to