Krzysztof Parzyszek via llvm-dev
2021-Sep-09 13:29 UTC
[llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode?
If we say that the fast-math flags are “enabling optimizations that the presence
of nans otherwise prohibits”, then there is no reason for clang to keep calls to
“isnan” around, or to keep checks like “fpclassify(x) == it’s_a_nan” unfolded.
These are exactly the types of optimizations that the presence of NaNs would
prohibit.
I understand the need for having some NaN-handling preserved in an otherwise
finite-math code. We already have fast-math-related attributes attached to each
function in the LLVM IR, so we could introduce a source-level attribute for
enabling/disabling these flags per function.
--
Krzysztof Parzyszek kparzysz at quicinc.com<mailto:kparzysz at
quicinc.com> AI tools development
From: cfe-dev <cfe-dev-bounces at lists.llvm.org> On Behalf Of Chris
Lattner via cfe-dev
Sent: Wednesday, September 8, 2021 5:51 PM
To: James Y Knight <jyknight at google.com>
Cc: LLVM Developers <llvm-dev at lists.llvm.org>; Clang Dev <cfe-dev at
lists.llvm.org>
Subject: Re: [cfe-dev] [llvm-dev] Should isnan be optimized out in fast-math
mode?
WARNING: This email originated from outside of Qualcomm. Please be wary of any
links or attachments, and do not enable macros.
On Sep 8, 2021, at 3:27 PM, James Y Knight via llvm-dev <llvm-dev at
lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote:
I expressed my strong support for this on the previous thread, but I'll just
repost the most important piece...
I believe the proposed semantics from the Clang level 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.
FWIW, I completely agree - these flags are about enabling optimizations that the
presence of nans otherwise prohibits. We shouldn’t take a literal
interpretation of an old GCC manual, as that would not be useful.
If we converge on this definition, I think it should be documented. This is a
source of confusion that comes up periodically.
-Chris
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.
In further support of this position, I note that the previous thread uncovered
at least one vendor -- Apple
(https://opensource.apple.com/source/Libm/Libm-2026/Source/Intel/math.h.auto.html)
-- going out of their way to cause isnan and friends to function properly with
-ffast-math enabled.
On Wed, Sep 8, 2021 at 1:02 PM Serge Pavlov via cfe-dev <cfe-dev at
lists.llvm.org<mailto:cfe-dev at lists.llvm.org>> wrote:
Hi all,
One of the purposes of `llvm::isnan` was to help preserve the check made by
`isnan` if fast-math mode is
specified (https://reviews.llvm.org/D104854). I'd like to describe reason
for that and propose to use the behavior
implemented in that patch.
The option `-ffast-math` is often used when performance is important, as it
allows a compiler to generate faster code.
This option itself is a collection of different optimization techniques, each
having its own option. For this topic only the
option `-ffinite-math-only` is of interest. With it the compiler treats floating
point numbers as mathematical real numbers,
so transformations like `0 * x -> 0` become valid.
In clang documentation
(https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math) this option
is described as:
"Allow floating-point optimizations that assume arguments and results
are not NaNs or +-Inf."
GCC documentation (https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html) is
a bit more concrete:
"Allow optimizations for floating-point arithmetic that assume that
arguments and results are not NaNs or +-Infs."
**What is the issue?**
C standard defines a macro `isnan`, which can be mapped to an intrinsic function
provided by the compiler. For both
clang and gcc it is `__builtin_isnan`. How should this function behave if
`-ffinite-math-only` is specified? Should it make a
real check or the compiler can assume that it always returns false?
GCC optimizes out `isnan`. It follows from the viewpoint that
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50724#c1):
"With -ffinite-math-only you are telling that there are no NaNs and
thus GCC optimizes isnan (x) to 0."
Such treatment of `-ffinite-math-only` has sufficient drawbacks. In particular
it makes it impossible to check validity of
data: a user cannot write
assert(!isnan(x));
because the compiler replaces the actual function call with its expected value.
There are many complaints in GCC bug
tracker (for instance https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949 or
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50724)
as well as in forums
(https://stackoverflow.com/questions/47703436/isnan-does-not-work-correctly-with-ofast-flags
or
https://stackoverflow.com/questions/22931147/stdisinf-does-not-work-with-ffast-math-how-to-check-for-infinity).
Proposed
solutions are using integer operations to make the check, to turn off
`-ffinite-math-only` in some parts of the code or to
ensure that libc function is called. It clearly demonstrates that `isnan` in
this case is useless, but users need its functionality
and do not have a proper tool to make required checks. The similar direction was
criticized in llvm as well (https://reviews.llvm.org/D18513#387418).
**Why imposing restrictions on floating types is bad?**
If `-ffinite-math-only` modifies properties of `double` type, several issues
arise, for instance:
- What should return `std::numeric_limits<double>::has_quiet_NaN()`?
- What body should have this function if it is used in a program where some
functions are compiled with `fast-math` and some without?
- Should inlining of a function compiled with `fast-math` to a function compiled
without it be prohibited in inliner?
- Should `std::isnan(std::numeric_limits<float>::quiet_NaN())` be true?
If the type `double` cannot have NaN value, it means that `double` and `double`
under `-ffinite-math-only` are different types
(https://gcc.gnu.org/pipermail/gcc-patches/2020-April/544641.html). Such a way
can solve these problems but it is so expensive
that hardly it has a chance to be realized.
**The solution**
Instead of modifying properties of floating point types, the effect of
`-ffinite-math-only` can be expressed as a restriction on
operation usage. Actually clang and gcc documentation already follows this way.
Fast-math flags in llvm IR also are attributes
of instructions. The only question is whether `isnan` and similar functions are
floating-point arithmetic.
From a practical viewpoint, treating non-computational functions as arithmetic
does not add any advantage. If a code extensively
uses `isnan` (so could profit by their removal), it is likely it is not suitable
for -ffinite-math-only. This interpretation however creates
the problems described above. So it is profitable to consider `isnan` and
similar functions as non-arithmetical.
**Why is it safe to leave `isnan`?**
The probable concern of this solution is deviation from gcc behavior. There are
several reasons why this is not an issue.
1. -ffinite-math-only is an optimization option. A correct program compiled with
-ffinite-math-only and without it should behave
identically, if conditions for using -ffinite-math-only are fulfilled. So
making the check cannot break functionality.
2. `isnan` is implemented by libc, which can map it to a compiler builtin or use
its own implementation, depending on
configuration options. `isnan` implemented in libc obviously always does the
real check.
3. ICC and MSVC preserve `isnan` in fast-math mode.
The proposal is to not consider `isnan` and other such functions as arithmetic
operations and do not optimize them out
just because -ffinite-math-only is specified. Of course, there are cases when
`isnan` may be optimized out, for instance,
`isnan(a + b)` may be optimized if -ffinite-math-only is in effect due to the
assumption (result of arithmetic operation is not NaN).
What are your opinions?
Thanks,
--Serge
_______________________________________________
cfe-dev mailing list
cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
_______________________________________________
LLVM Developers mailing list
llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20210909/50802290/attachment-0001.html>
Sanjay Patel via llvm-dev
2021-Sep-09 15:02 UTC
[llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode?
Not sure which way to go, but I agree that we need to improve the docs/user
experience either way.
Let's try to iron this out with an example (this is based on
https://llvm.org/PR51775 ):
#include <math.h>
#include <stdlib.h>
int main() {
const double d = strtod("1E+1000000", NULL);
return d == HUGE_VAL;
}
What should this program return when compiled with -ffinite-math-only?
Should this trigger a clang warning?
https://godbolt.org/z/MY73Tf3ee
The proposed documentation text isn't clear to me. Should clang apply
"nnan
ninf" to the IR call for "strtod"?
"strtod" is not in the enumerated list of functions where we would
block
fast-math-flags, but it is a standard lib call, so "nnan ninf" would
seem
to apply...but we also don't want "-ffinite-math-only" to alter
the ability
to return an INF from a "general function call"?
On Thu, Sep 9, 2021 at 9:30 AM Krzysztof Parzyszek via cfe-dev <
cfe-dev at lists.llvm.org> wrote:
> If we say that the fast-math flags are “enabling optimizations that the
> presence of nans otherwise prohibits”, then there is no reason for clang to
> keep calls to “isnan” around, or to keep checks like “fpclassify(x) =>
it’s_a_nan” unfolded. These are exactly the types of optimizations that
> the presence of NaNs would prohibit.
>
>
>
> I understand the need for having some NaN-handling preserved in an
> otherwise finite-math code. We already have fast-math-related attributes
> attached to each function in the LLVM IR, so we could introduce a
> source-level attribute for enabling/disabling these flags per function.
>
>
>
>
>
> --
>
> Krzysztof Parzyszek kparzysz at quicinc.com AI tools development
>
>
>
> *From:* cfe-dev <cfe-dev-bounces at lists.llvm.org> *On Behalf Of
*Chris
> Lattner via cfe-dev
> *Sent:* Wednesday, September 8, 2021 5:51 PM
> *To:* James Y Knight <jyknight at google.com>
> *Cc:* LLVM Developers <llvm-dev at lists.llvm.org>; Clang Dev <
> cfe-dev at lists.llvm.org>
> *Subject:* Re: [cfe-dev] [llvm-dev] Should isnan be optimized out in
> fast-math mode?
>
>
>
> *WARNING:* This email originated from outside of Qualcomm. Please be wary
> of any links or attachments, and do not enable macros.
>
> On Sep 8, 2021, at 3:27 PM, James Y Knight via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>
>
> I expressed my strong support for this on the previous thread, but I'll
> just repost the most important piece...
>
>
>
> I believe the proposed semantics from the Clang level 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.
>
>
>
> FWIW, I completely agree - these flags are about enabling optimizations
> that the presence of nans otherwise prohibits. We shouldn’t take a literal
> interpretation of an old GCC manual, as that would not be useful.
>
>
>
> If we converge on this definition, I think it should be documented. This
> is a source of confusion that comes up periodically.
>
>
>
> -Chris
>
>
>
>
>
>
>
> 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.
>
>
>
> In further support of this position, I note that the previous thread
> uncovered at least one vendor -- Apple (
>
https://opensource.apple.com/source/Libm/Libm-2026/Source/Intel/math.h.auto.html)
> -- going out of their way to cause isnan and friends to function properly
> with -ffast-math enabled.
>
>
>
>
>
>
>
> On Wed, Sep 8, 2021 at 1:02 PM Serge Pavlov via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
> Hi all,
>
>
>
> One of the purposes of `llvm::isnan` was to help preserve the check made
> by `isnan` if fast-math mode is
>
> specified (https://reviews.llvm.org/D104854). I'd like to describe
reason
> for that and propose to use the behavior
>
> implemented in that patch.
>
>
>
> The option `-ffast-math` is often used when performance is important, as
> it allows a compiler to generate faster code.
>
> This option itself is a collection of different optimization techniques,
> each having its own option. For this topic only the
>
> option `-ffinite-math-only` is of interest. With it the compiler treats
> floating point numbers as mathematical real numbers,
>
> so transformations like `0 * x -> 0` become valid.
>
>
>
> In clang documentation (
> https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math) this
> option is described as:
>
> "Allow floating-point optimizations that assume arguments and
results
> are not NaNs or +-Inf."
>
> GCC documentation (
> https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html) is a bit more
> concrete:
>
> "Allow optimizations for floating-point arithmetic that assume
that
> arguments and results are not NaNs or +-Infs."
>
>
>
> **What is the issue?**
>
> C standard defines a macro `isnan`, which can be mapped to an intrinsic
> function provided by the compiler. For both
>
> clang and gcc it is `__builtin_isnan`. How should this function behave if
> `-ffinite-math-only` is specified? Should it make a
>
> real check or the compiler can assume that it always returns false?
>
> GCC optimizes out `isnan`. It follows from the viewpoint that (
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50724#c1):
>
> "With -ffinite-math-only you are telling that there are no NaNs
and
> thus GCC optimizes isnan (x) to 0."
>
>
>
> Such treatment of `-ffinite-math-only` has sufficient drawbacks. In
> particular it makes it impossible to check validity of
>
> data: a user cannot write
>
>
>
> assert(!isnan(x));
>
>
>
> because the compiler replaces the actual function call with its expected
> value. There are many complaints in GCC bug
>
> tracker (for instance https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949
> or https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50724)
>
> as well as in forums (
>
https://stackoverflow.com/questions/47703436/isnan-does-not-work-correctly-with-ofast-flags
> or
>
>
https://stackoverflow.com/questions/22931147/stdisinf-does-not-work-with-ffast-math-how-to-check-for-infinity).
> Proposed
>
> solutions are using integer operations to make the check, to turn off
> `-ffinite-math-only` in some parts of the code or to
>
> ensure that libc function is called. It clearly demonstrates that `isnan`
> in this case is useless, but users need its functionality
>
> and do not have a proper tool to make required checks. The similar
> direction was criticized in llvm as well (
> https://reviews.llvm.org/D18513#387418).
>
>
>
> **Why imposing restrictions on floating types is bad?**
>
> If `-ffinite-math-only` modifies properties of `double` type, several
> issues arise, for instance:
> - What should return `std::numeric_limits<double>::has_quiet_NaN()`?
> - What body should have this function if it is used in a program where
> some functions are compiled with `fast-math` and some without?
> - Should inlining of a function compiled with `fast-math` to a function
> compiled without it be prohibited in inliner?
> - Should `std::isnan(std::numeric_limits<float>::quiet_NaN())` be
true?
>
> If the type `double` cannot have NaN value, it means that `double` and
> `double` under `-ffinite-math-only` are different types
>
> (https://gcc.gnu.org/pipermail/gcc-patches/2020-April/544641.html). Such
> a way can solve these problems but it is so expensive
>
> that hardly it has a chance to be realized.
>
>
>
> **The solution**
>
> Instead of modifying properties of floating point types, the effect of
> `-ffinite-math-only` can be expressed as a restriction on
>
> operation usage. Actually clang and gcc documentation already follows
> this way. Fast-math flags in llvm IR also are attributes
>
> of instructions. The only question is whether `isnan` and similar
> functions are floating-point arithmetic.
>
> From a practical viewpoint, treating non-computational functions as
> arithmetic does not add any advantage. If a code extensively
>
> uses `isnan` (so could profit by their removal), it is likely it is not
> suitable for -ffinite-math-only. This interpretation however creates
>
> the problems described above. So it is profitable to consider `isnan` and
> similar functions as non-arithmetical.
>
>
>
> **Why is it safe to leave `isnan`?**
>
> The probable concern of this solution is deviation from gcc behavior.
> There are several reasons why this is not an issue.
>
> 1. -ffinite-math-only is an optimization option. A correct program
> compiled with -ffinite-math-only and without it should behave
>
> identically, if conditions for using -ffinite-math-only are fulfilled.
> So making the check cannot break functionality.
> 2. `isnan` is implemented by libc, which can map it to a compiler builtin
> or use its own implementation, depending on
>
> configuration options. `isnan` implemented in libc obviously always
> does the real check.
> 3. ICC and MSVC preserve `isnan` in fast-math mode.
>
>
>
> The proposal is to not consider `isnan` and other such functions as
> arithmetic operations and do not optimize them out
>
> just because -ffinite-math-only is specified. Of course, there are cases
> when `isnan` may be optimized out, for instance,
>
> `isnan(a + b)` may be optimized if -ffinite-math-only is in effect due to
> the assumption (result of arithmetic operation is not NaN).
>
> What are your opinions?
>
> Thanks,
> --Serge
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20210909/69a528f8/attachment.html>
Serge Pavlov via llvm-dev
2021-Sep-09 16:09 UTC
[llvm-dev] [cfe-dev] Should isnan be optimized out in fast-math mode?
On Thu, Sep 9, 2021 at 8:30 PM Krzysztof Parzyszek via cfe-dev < cfe-dev at lists.llvm.org> wrote:> If we say that the fast-math flags are “enabling optimizations that the > presence of nans otherwise prohibits”, then there is no reason for clang to > keep calls to “isnan” around, or to keep checks like “fpclassify(x) => it’s_a_nan” unfolded. These are exactly the types of optimizations that > the presence of NaNs would prohibit. >Transformation 'x * 0 -> 0' is an optimization allowed in the absence of nans as arguments, because it produces a program that behaves identically under the given restrictions. Replacement of `isnan(x + x)` is also an optimization under the same restrictions. Replacement of `isnan(x)` in general case is not, because we cannot assume that x cannot be a NaN.> > I understand the need for having some NaN-handling preserved in an > otherwise finite-math code. We already have fast-math-related attributes > attached to each function in the LLVM IR, so we could introduce a > source-level attribute for enabling/disabling these flags per function. >GCC allows using `#pragma GCC optimize ("finite-math-only")` or `#pragma GCC optimize ("no-finite-math-only")` to enable/disable optimization per function basis. Clang could support this pragmf or maybe `#pragma clang fp` can be extended to support similar functionality.> > > > -- > > Krzysztof Parzyszek kparzysz at quicinc.com AI tools development > > > > *From:* cfe-dev <cfe-dev-bounces at lists.llvm.org> *On Behalf Of *Chris > Lattner via cfe-dev > *Sent:* Wednesday, September 8, 2021 5:51 PM > *To:* James Y Knight <jyknight at google.com> > *Cc:* LLVM Developers <llvm-dev at lists.llvm.org>; Clang Dev < > cfe-dev at lists.llvm.org> > *Subject:* Re: [cfe-dev] [llvm-dev] Should isnan be optimized out in > fast-math mode? > > > > *WARNING:* This email originated from outside of Qualcomm. Please be wary > of any links or attachments, and do not enable macros. > > On Sep 8, 2021, at 3:27 PM, James Y Knight via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > > > I expressed my strong support for this on the previous thread, but I'll > just repost the most important piece... > > > > I believe the proposed semantics from the Clang level 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. > > > > FWIW, I completely agree - these flags are about enabling optimizations > that the presence of nans otherwise prohibits. We shouldn’t take a literal > interpretation of an old GCC manual, as that would not be useful. > > > > If we converge on this definition, I think it should be documented. This > is a source of confusion that comes up periodically. > > > > -Chris > > > > > > > > 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. > > > > In further support of this position, I note that the previous thread > uncovered at least one vendor -- Apple ( > https://opensource.apple.com/source/Libm/Libm-2026/Source/Intel/math.h.auto.html) > -- going out of their way to cause isnan and friends to function properly > with -ffast-math enabled. > > > > > > > > On Wed, Sep 8, 2021 at 1:02 PM Serge Pavlov via cfe-dev < > cfe-dev at lists.llvm.org> wrote: > > Hi all, > > > > One of the purposes of `llvm::isnan` was to help preserve the check made > by `isnan` if fast-math mode is > > specified (https://reviews.llvm.org/D104854). I'd like to describe reason > for that and propose to use the behavior > > implemented in that patch. > > > > The option `-ffast-math` is often used when performance is important, as > it allows a compiler to generate faster code. > > This option itself is a collection of different optimization techniques, > each having its own option. For this topic only the > > option `-ffinite-math-only` is of interest. With it the compiler treats > floating point numbers as mathematical real numbers, > > so transformations like `0 * x -> 0` become valid. > > > > In clang documentation ( > https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math) this > option is described as: > > "Allow floating-point optimizations that assume arguments and results > are not NaNs or +-Inf." > > GCC documentation ( > https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html) is a bit more > concrete: > > "Allow optimizations for floating-point arithmetic that assume that > arguments and results are not NaNs or +-Infs." > > > > **What is the issue?** > > C standard defines a macro `isnan`, which can be mapped to an intrinsic > function provided by the compiler. For both > > clang and gcc it is `__builtin_isnan`. How should this function behave if > `-ffinite-math-only` is specified? Should it make a > > real check or the compiler can assume that it always returns false? > > GCC optimizes out `isnan`. It follows from the viewpoint that ( > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50724#c1): > > "With -ffinite-math-only you are telling that there are no NaNs and > thus GCC optimizes isnan (x) to 0." > > > > Such treatment of `-ffinite-math-only` has sufficient drawbacks. In > particular it makes it impossible to check validity of > > data: a user cannot write > > > > assert(!isnan(x)); > > > > because the compiler replaces the actual function call with its expected > value. There are many complaints in GCC bug > > tracker (for instance https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949 > or https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50724) > > as well as in forums ( > https://stackoverflow.com/questions/47703436/isnan-does-not-work-correctly-with-ofast-flags > or > > https://stackoverflow.com/questions/22931147/stdisinf-does-not-work-with-ffast-math-how-to-check-for-infinity). > Proposed > > solutions are using integer operations to make the check, to turn off > `-ffinite-math-only` in some parts of the code or to > > ensure that libc function is called. It clearly demonstrates that `isnan` > in this case is useless, but users need its functionality > > and do not have a proper tool to make required checks. The similar > direction was criticized in llvm as well ( > https://reviews.llvm.org/D18513#387418). > > > > **Why imposing restrictions on floating types is bad?** > > If `-ffinite-math-only` modifies properties of `double` type, several > issues arise, for instance: > - What should return `std::numeric_limits<double>::has_quiet_NaN()`? > - What body should have this function if it is used in a program where > some functions are compiled with `fast-math` and some without? > - Should inlining of a function compiled with `fast-math` to a function > compiled without it be prohibited in inliner? > - Should `std::isnan(std::numeric_limits<float>::quiet_NaN())` be true? > > If the type `double` cannot have NaN value, it means that `double` and > `double` under `-ffinite-math-only` are different types > > (https://gcc.gnu.org/pipermail/gcc-patches/2020-April/544641.html). Such > a way can solve these problems but it is so expensive > > that hardly it has a chance to be realized. > > > > **The solution** > > Instead of modifying properties of floating point types, the effect of > `-ffinite-math-only` can be expressed as a restriction on > > operation usage. Actually clang and gcc documentation already follows > this way. Fast-math flags in llvm IR also are attributes > > of instructions. The only question is whether `isnan` and similar > functions are floating-point arithmetic. > > From a practical viewpoint, treating non-computational functions as > arithmetic does not add any advantage. If a code extensively > > uses `isnan` (so could profit by their removal), it is likely it is not > suitable for -ffinite-math-only. This interpretation however creates > > the problems described above. So it is profitable to consider `isnan` and > similar functions as non-arithmetical. > > > > **Why is it safe to leave `isnan`?** > > The probable concern of this solution is deviation from gcc behavior. > There are several reasons why this is not an issue. > > 1. -ffinite-math-only is an optimization option. A correct program > compiled with -ffinite-math-only and without it should behave > > identically, if conditions for using -ffinite-math-only are fulfilled. > So making the check cannot break functionality. > 2. `isnan` is implemented by libc, which can map it to a compiler builtin > or use its own implementation, depending on > > configuration options. `isnan` implemented in libc obviously always > does the real check. > 3. ICC and MSVC preserve `isnan` in fast-math mode. > > > > The proposal is to not consider `isnan` and other such functions as > arithmetic operations and do not optimize them out > > just because -ffinite-math-only is specified. Of course, there are cases > when `isnan` may be optimized out, for instance, > > `isnan(a + b)` may be optimized if -ffinite-math-only is in effect due to > the assumption (result of arithmetic operation is not NaN). > > What are your opinions? > > Thanks, > --Serge > > _______________________________________________ > cfe-dev mailing list > cfe-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > _______________________________________________ > cfe-dev mailing list > cfe-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210909/66a8a54d/attachment-0001.html>