#1563: Provide always-working isnan etc. -------------------------+-------------------------------------------------- Reporter: eschnett | Owner: Type: enhancement | Status: new Priority: major | Milestone: Component: Cactus | Version: development version Keywords: | -------------------------+-------------------------------------------------- Certain math optimization options (e.g. -ffast-math) tell the compiler that IEEE floating point numbers such as inf and nan do not need to be handled correctly (in the sense specified by the IEEE standard). This greatly improves floating-point speed and is commonly used in numerical HPC applications.
For example, fmax() specifies: {{{ If exactly one argument is a NaN, fmax() returns the other argument. If both arguments are NaNs, fmax() returns a NaN. }}} Implementing this correctly requires checking whether each argument is a nan. To improve speed, one can omit this check, which means that fmax() may return NaN, even if one of its argument is not a NaN. This is fine in most cases, and people appreciate the added speed.
However, since compilers then don't need to handle inf and nan correctly, they have begun to optimise isnan(x) to simply returning false all the time. This improves speed (since the check does not actually need to occur) and reduces code size (since the nan-handling if branches can be omitted). Of course, this makes it then impossible to actually check for nan by calling isnan.
Currently, e.g. g++ performs this optimisation, whereas gcc does not. Things vary with other compilers. In the future, with link-time optimisations, I expect other compilers to follow g++.
The enclosed patch provides functions CCTK_IEEE_isnan etc. that always check for nan, independent of the chosen optimisation flags.