<div dir="ltr"><div class="gmail_quote">[ I previously sent this to a smaller group, but would also appreciate feedback from this group as well. Was it considered that IEC 60559 conformance is essentially not determinable at compile time? ]</div><div class="gmail_quote"><br><div dir="ltr">While discussing my WG21/SG6 proposal to deprecate fenv-based rounding in C++ (wg21.link/p2746), Matthias Kretz raised the issue of code run in flush-to-zero mode. I had thought that had largely disappeared for CPU-executed code, but it actually seems quite common on X86. Based on a quick look, ARM is similar, though RISC-V is currently not, I think.<div><br></div><div>I investigated this while trying to generate the next paper revision (which will be delayed, partly as a result). The current draft of my conclusions is below. But my overall conclusion is that this is a bit of a mess, and probably one I want to largely ignore for now. But I'd appreciate any insights you may have. (Feel free to forward, if you like. I can also post to the cfp and sg6 groups, but I wanted to ask you for feedback first.)</div><div><br></div><div>It appears to me that the 60559-conformance macros defined in C23 are essentially unimplementable on modern x86 platforms, because there is no way to know until runtime whether the hardware is conformant; it depends on what code was run at startup-time, or possibly later if somebody decides to switch the flush-to-zero bits in the middle. And the macros may or may not indicate what the programmer actually wants to know. I expect that some code will want to treat a 60559-except-flush-to-zero platform as conformant, and clearly some will not.</div><div><br></div><div>Current draft of summary for wg21.link/p2746:</div><div><br></div><div>It was pointed out that it is common to disable subnormals/denormals/gradual underflow on x86, and changing this locally around cr_ library calls is probably infeasible.<br><br>Further investigation showed:</div><div><br></div><div>Implementations other than x87 (SSE and later) commonly need software assist for gradual underflow, potentially making performance unacceptable when dealing with many near-zero values. Gcc provides the -mdaz-ftz (denormals are zero, flush to zero) flag for this purpose. It appears to be implemented entirely by including code that sets a hardware flag; constants are unaffected. <br><br>This seems to be most commonly enabled by -ffast-math.<br><br>This mode is not IEC 60559 conformant. The C standard also says “IEC 60559 arithmetic (with default exception handling) always treats subnormal numbers as nonzero”. Clang does not support it as an explicit flag, though -ffast-math may have a similar effect. (This seems to depend on installation details.) As one might expect, it is highly controversial. It is also brittle since it can apparently affect code not expecting to run in this mode. (See e.g. <a href="https://moyix.blogspot.com/2022/09/someones-been-messing-with-my-subnormals.html" target="_blank">https://moyix.blogspot.com/2022/09/someones-been-messing-with-my-subnormals.html</a>, which I found through a clang discussion.)</div><div><br></div><div>It is hard to make compiler-provided information about 60559 conformance accurate, given that behavior with respect to subnormals is controlled by a runtime flag. Gcc sets __STDC_IEC_559__ with -mdaz-ftz, but not with -ffast-math.<br><br>My current conclusion is that this is a bit of a mess, which we should largely try to dodge. A standard-conforming implementation should not claim to be 60559 compliant unless it can turn off flush-to-zero for those operations.<br><br></div><div>Hans</div></div>
</div></div>