[Bug libstdc++/84949] -ffast-math bugged with respect to NaNs
rguenther at suse dot de
gcc-bugzilla@gcc.gnu.org
Tue May 8 07:35:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949
--- Comment #5 from rguenther at suse dot de <rguenther at suse dot de> ---
On Thu, 3 May 2018, redi at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84949
>
> --- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
> std::numeric_limits<float> defines:
>
> static _GLIBCXX_USE_CONSTEXPR bool has_infinity = __FLT_HAS_INFINITY__;
> static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = __FLT_HAS_QUIET_NAN__;
> static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = has_quiet_NaN;
> static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
> = bool(__FLT_HAS_DENORM__) ? denorm_present : denorm_absent;
> //...
> static _GLIBCXX_USE_CONSTEXPR bool is_iec559
> = has_infinity && has_quiet_NaN && has_denorm == denorm_present;
^^^
note that this really can't work in a way to reflect the state
of flags like -ffinite-math-only because those can be different
_per function_. Of course then the preprocessor macros do not
reflect reality either...
bool __attribute__((optimize("finite-math-only")))
isnan1 (double x, int &a)
{
a = __FINITE_MATH_ONLY__;
return __builtin_isnan(x);
}
bool __attribute__((optimize("no-finite-math-only")))
isnan2 (double x, int &a)
{
a = __FINITE_MATH_ONLY__;
return __builtin_isnan(x);
}
int main()
{
int a;
__builtin_printf ("%d %d\n", isnan1(__builtin_nan(""), a), a);
__builtin_printf ("%d %d\n", isnan2(__builtin_nan(""), a), a);
}
> g++-7 t.c
> ./a.out
0 0
1 0
> g++-7 t.c -ffinite-math-only
> ./a.out
0 0
1 1
note that __FLT_HAS_QUIET_NAN__ is not affected by flags.
> And that seems to be the right thing to do. If the compiler tells us the type
> has infinities and NaNs then we expose that through std::numeric_limits.
>
> I don't think we want the C++ library to be inconsistent with the compiler
> here. So maybe any change should be in the compiler not libstdc++.
So my points in comment#1 still stand. It might be unfortunate
(even more so since you can't actually rely on __FINITE_MATH_ONLY__)
but it's not likely to change (people have repeatedly requested
that at least isnan() continues to return true for NaNs for example).
More information about the Gcc-bugs
mailing list