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

Reply via email to