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