------- Comment #14 from iano at apple dot com 2006-08-22 18:25 -------
For your amusement:
[ollmia:/tmp] iano% cat main.c
#include <stdio.h>
extern int __isnand( double );
static __inline__ int __inline_isnan( double __a )
{
if( __builtin_isnan( __builtin_nan("") ) )
return __builtin_isnan( __a );
return __isnand( __a); //this is our isnan() compiled in a separate
compilation unit that always works
}
int main( void )
{
volatile double g = __builtin_nan("");
printf( "isnan(%g) = %d\n", g, __inline_isnan( g ) );
return 0;
}
[ollmia:/tmp] iano% gcc main.c -O0 -g -ffast-math ; ./a.out
isnan(nan) = 0
If you step through in gdb, we see that what the compiler has done here is use
the IEEE compare result to determine that __builtin_isnan( __builtin_nan("") )
is always true. It faills through to the next line where, __builtin_isnan()
returns always false.
For reasons I can't explain, we also see this:
[ollmia:/tmp] iano% cat main.c
#include <stdio.h>
extern int __isnand( double );
static __inline__ int __inline_isnan( double __a )
{
static const double nan = __builtin_nan("");
if( nan != nan )
return __a != __a;
return __isnand( __a);
}
int main( void )
{
volatile double g = __builtin_nan("");
printf( "isnan(%g) = %d\n", g, __inline_isnan( g ) );
return 0;
}
[ollmia:/tmp] iano% gcc main.c -O0 -g -ffast-math ; ./a.out
isnan(nan) = 1
[ollmia:/tmp] iano% gcc main.c -O3 -g -ffast-math ; ./a.out
isnan(nan) = 0
[ollmia:/tmp] iano% gcc main.c -O0 -g -ffinite-math-only ; ./a.out
isnan(nan) = 1
[ollmia:/tmp] iano% gcc main.c -O3 -g -ffinite-math-only ; ./a.out
isnan(nan) = 0
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796