sepavloff added a comment. In D89360#2330522 <https://reviews.llvm.org/D89360#2330522>, @rsmith wrote:
> In D89360#2329856 <https://reviews.llvm.org/D89360#2329856>, @sepavloff wrote: > >> I would propose to consider solution in D88498 >> <https://reviews.llvm.org/D88498>. It tries to fix the real reason of the >> malfunction - using dynamic rounding mode for evaluation of global variable >> initializers. > > That is not the real reason for the malfunction. If you narrowly look at C, > you can convince yourself otherwise, but that's only because global variable > initializers are the only place where we need to evaluate floating-point > constant expressions in C. In C++, this problem affects all contexts where > constant evaluation might happen (array bounds, bit-field widths, and a whole > host of others). You are right, the solution in D88498 <https://reviews.llvm.org/D88498> was more a workaround, as it was focused on initializers only. The updated version applies dynamic rounding to function bodies only, I hope it could solve the problem of other contexts. ================ Comment at: clang/test/SemaCXX/rounding-math.cpp:9 + +constexpr int f(int n) { return int(n * (1.0 / 3.0)); } + ---------------- rsmith wrote: > rsmith wrote: > > sepavloff wrote: > > > This code requires additional solution. The function body is built using > > > dynamic rounding mode, which breaks its constexprness. We can avoid this > > > kind of errors if we assume that body of a constexpr function is parsed > > > using constant rounding mode (in this example it is the default mode). It > > > makes parsing constexpr function different from non-constexpr ones, but > > > enables convenient use: > > > ``` > > > constexpr int add(float x, float y) { return x + y; } > > > > > > #pragma STDC FENV_ROUND FE_UPWARD > > > int a2 = add(2.0F, 0x1.000002p0F); > > > > > > #pragma STDC FENV_ROUND FE_DOWNWARD > > > int a3 = add(2.0F, 0x1.000002p0F); > > > ``` > > > If calls of constexpr functions are processes with FP options acting in > > > the call site, a call to constexpr function becomes equivalent to > > > execution of statements of its body. > > I don't understand what you mean by "breaks its constexprness". Using a > > dynamic rounding mode for the body of the function is exactly what we want > > here. When the function is called in a manifestly constant evaluated > > context, we should use the default rounding mode, and when it's called at > > runtime, we use the appropriate dynamic rounding mode; if we try to > > constant evaluate it outside of a manifestly constant evaluated constant, > > we deem it non-constant. > > > > When `constexpr` function is called at runtime, it's a completely normal > > function with normal semantics. It would be wrong to use the default > > rounding mode when parsing its body. > To be clear: in your example with `add`, both `a2` and `a3` should be > initialized to the same value, which should be rounded with the default > rounding mode. Per ISO18661, `FENV_ROUND` only affects operations in its > lexical scope, not functions called within those operations, and per the > regular C++ rules, `constexpr` functions behave like regular functions, not > like macros. I incorrectly identified the reason why some call was rejected in constant evaluated context. Please ignore this statement. I am sorry. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D89360/new/ https://reviews.llvm.org/D89360 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits