[PATCH] D89360: Treat constant contexts as being in the default rounding mode.

Richard Smith - zygoloid via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 14 10:33:27 PDT 2020


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



More information about the cfe-commits mailing list