[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


--- 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)
  return __builtin_isnan(x);
bool __attribute__((optimize("no-finite-math-only")))
isnan2 (double x, int &a)
  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