[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 16:39:11 PDT 2020


rsmith added inline comments.


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


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