[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
Fri Oct 16 12:39:17 PDT 2020


rsmith added a comment.

In D89360#2329167 <https://reviews.llvm.org/D89360#2329167>, @rjmccall wrote:

> Okay.  I can accept the fairly unfortunate thing with `const int` initializers.  When is `IsConstantContext` set in C, just static initializers?

This affects static initializers, enumerators, bit-widths, array bounds, case labels, and indexes in array designators. For code not relying on extensions, only static initializers are affected, but as an extension we do permit floating-point math in other contexts. I've added some tests for the C side of things to demonstrate.

The C tests reveal one issue: block-scope array bounds get constant-folded in GNU mode even if they contain floating-point operations. That's PR44406; D89523 <https://reviews.llvm.org/D89523> and D89520 <https://reviews.llvm.org/D89520> have a fix for that which should hopefully land soon. I don't think we need to block on it.

In D89360#2334038 <https://reviews.llvm.org/D89360#2334038>, @sepavloff wrote:

> Probably there is an issue with code generation. The source:
>
>   constexpr float func_01(float x, float y) {
>     return x + y;
>   }
>   
>   float V1 = func_01(1.0F, 0x0.000001p0F);
>
> compiled with '-frounding-math' must produce dynamic initializer. It however is evaluated at compile time.

Evaluating it at compile time is in line with the plan from https://reviews.llvm.org/D87528#2270676. The C++ rule is that initializers for static storage duration variables are first evaluated during translation (therefore, per our plan, in the default rounding mode), and only evaluated at runtime (and therefore in the runtime rounding mode) if the compile-time evaluation fails. This is in line with the C rules; C11 F.8.5 says: "All computation for automatic initialization is done (as if) at execution time; thus, it is affected by any operative modes and raises floating-point exceptions as required by IEC 60559 (provided the state for the FENV_ACCESS pragma is β€˜β€˜on’’). All computation for initialization of objects that have static or thread storage duration is done (as if) at translation time." C++ generalizes this by adding another phase of initialization (at runtime) if the translation-time initialization fails, but the translation-time evaluation of the initializer of `V1` succeeds so it should be treated as a constant initializer.

And just a side note: we're currently blocked by this. C++ builds using `-frounding-math` have not worked at all since D87822 <https://reviews.llvm.org/D87822> landed. If we can't come to an agreement on a fix very soon, I think we need to revert D87822 <https://reviews.llvm.org/D87822> while we figure it out.


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