[cfe-dev] [llvm-dev] Intrinsic llvm::isnan

Serge Pavlov via cfe-dev cfe-dev at lists.llvm.org
Wed Aug 25 04:12:48 PDT 2021

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949 was mentioned as
>> motivational, but i don't see any resolution there,
>> it's not even in "confirmed" state.
> I agree, this is not at all clear evidence as to GCC's position on the
> matter.

Sure, but that demonstrates that they are inclined to such interpretation.

GCC mail list has relevant discussion on this topic:
https://gcc.gnu.org/pipermail/gcc-patches/2020-April/544622.html. They
tried to make the documentation about -ffinite-math-only clearer. The
discussion was based on a view that if -ffinite-math-only was specified, a
floating point value cannot be NaN or Inf. During the discussion an
interesting observation was made:

… double and double under -ffinite-math-only are different types. Any
> function call from
> one world to the other is dangerous. Inline functions translated in
> different
> TUs compiled with different math flags violate the ODR.

If different parts of a program are compiled with and without
-ffinite-math-only doubles of different flavors can intermix. In the code
compiled with -ffast-math a user cannot check assumption about the value by
calling "assert(!isnan(x));" because `isnan` is replaced with expected
value due to optimizations. The only usable solution in this case could be
UBSAN, which is a much heavier solution.

Two different flavors of double require different mangling. Template
specializations also must be different, in particular, specializations of
`std::numeric_limits<T>` must be different for these two double types, the
methods `has_infinity` and `has_quite_NaN` must return different values.

They agree that it is profitable to treat NaNs and Infs separately. In this
case there would be 4 different double types. It is not clear what to do
with constexpr expressions, should the compiler treat using NaN/Inf as
undefined behavior even if the ultimate result is finite?

Participants agree that such optimizations are not good:

 … the example of simplifying x * 0 to 0 is about preserving NaNs
> during expression simplification when the FPU would.  I think these
> kind of optimizations are what originally was intended to be allowed
> with -ffinite-math-only - that we started to simplify isnan(x) to false
> was extending the scope and that change wasn't uncontested since
> it makes -ffinite-math-only less useful to some people.

Eventually they came to conclusion:

… if we want a version of
> -ffinite-math-only that's well-behaved in language terms (including
> in terms of the macros that are defined and in the values of
> numeric_limits), perhaps this should be an official (optional) C/C++
> extension that defines what the rules are.


On Wed, Aug 25, 2021 at 4:25 AM James Y Knight <jyknight at google.com> wrote:

> On Tue, Aug 24, 2021 at 1:53 PM Roman Lebedev via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>> Regardless of everything, i would like to see a patch that restores
>> the -ffast-math handling, and *then* the RFC on what the is-nan check
>> should do when -ffast-math is present.
>> It is more than possible that the RFC will succeed,
>> but i don't think a change like that should happen the way it did.
> I find the rationale to be convincing, as to the need for a change. But,
> the scope of the proposal is too narrow. We cannot discuss fast-math
> semantics changes *only* for "isnan", it needs to be in the context of
> the desired behavior for all operations -- the RFC should cover the entire
> set of changes we want to eventually make, even if isnan is the only thing
> implemented so far. Discussing this greater scope could result in a
> different desired implementation, rather than simply adding "llvm.isnan"
> intrinsic.
> Yet, even with that expanded scope, the two halves of the proposal are
> still going to be closely linked, so I suspect it still makes sense to
> discuss both the strict-fp and fast-math changes in a single RFC.
> Anyhow, for the fast-math section, I believe the proposed semantics ought
> to be:
>   The -ffinite-math-only and -fno-signed-zeros options do not impact the
> ability to accurately load, store, copy, or pass or return such values from
> general function calls. They also do not impact any of the
> "non-computational" and "quiet-computational" IEEE-754 operations, which
> includes classification functions (fpclassify, signbit, isinf/isnan/etc),
> sign-modification (copysign, fabs, and negation `-(x)`), as well as
> the totalorder and totalordermag functions. Those correctly handle NaN,
> Inf, and signed zeros even when the flags are in effect. These flags *do* affect
> the behavior of other expressions and math standard-library calls, as well
> as comparison operations.
> I would not expect this to have an actual negative impact on the
> performance benefit of those flags, since the optimization benefits mainly
> arise from comparisons and the general computation instructions which are
> unchanged.
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949 was mentioned as
>> motivational, but i don't see any resolution there,
>> it's not even in "confirmed" state.
> I agree, this is not at all clear evidence as to GCC's position on the
> matter.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20210825/02096364/attachment.html>

More information about the cfe-dev mailing list