rsmith added a comment.

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).

D88498 <https://reviews.llvm.org/D88498>'s approach also can't correctly handle 
`constexpr` functions, for which we want different behavior depending on 
whether the *caller* is a manifestly constant evaluated context.



================
Comment at: clang/test/SemaCXX/rounding-math.cpp:9
+
+constexpr int f(int n) { return int(n * (1.0 / 3.0)); }
+
----------------
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.


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