Bug 60237 - isnan fails with -ffast-math
Summary: isnan fails with -ffast-math
Status: RESOLVED DUPLICATE of bug 25975
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.1
: P3 major
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-17 10:41 UTC by N Schaeffer
Modified: 2014-02-17 17:28 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description N Schaeffer 2014-02-17 10:41:48 UTC
With -ffast-math, isnan should return true if passed a NaN value.
Otherwise, how is isnan different than (x!=x) ?

isnan worked as expected with gcc 4.7, but does not with 4.8.1 and 4.8.2

How can I check if x is a NaN in a portable way (not presuming any compilation option) ?
Comment 1 Jakub Jelinek 2014-02-17 10:53:06 UTC
Well, -ffast-math implies -ffinite-math-only, so the compiler is assuming no NaNs or infinites are used as arguments/return values of any expression.  So, if you have a program that produces NaNs anyway, you shouldn't be building it with -ffast-math, at least not with -ffinite-math-only.
Comment 2 N Schaeffer 2014-02-17 11:16:13 UTC
Thank you for your answer.

My program (which is a computational fluid dynamics solver) is not supposed to produce NaNs. However, when it does (which means something went wrong), I would like to abort the program and return an error instead of continuing crunching NaNs.
I also want it to run as fast as possible (hence the -ffast-math option).

I would argue that: if printf("%f",x) outputs "NaN", isnan(x) should also be returning true.

Do you have a suggestion concerning my last question:
How can I check if x is NaN in a portable way (not presuming any compilation option) ?
Comment 3 Marc Glisse 2014-02-17 11:26:03 UTC
(In reply to N Schaeffer from comment #2)
> Do you have a suggestion concerning my last question:
> How can I check if x is NaN in a portable way (not presuming any compilation
> option) ?

This should bypass software optimizations. But if the hardware is put in a mode that does strange things with NaN, it will be harder to work around.

int my_isnan(double x){
  volatile double y=x;
  return y!=y;
}
Comment 4 N Schaeffer 2014-02-17 11:38:37 UTC
int my_isnan(double x){
  volatile double y=x;
  return y!=y;
}

is translated to:
   0x0000000000406cf0 <+0>:     movsd  QWORD PTR [rsp-0x8],xmm0
   0x0000000000406cf6 <+6>:     xor    eax,eax
   0x0000000000406cf8 <+8>:     movsd  xmm1,QWORD PTR [rsp-0x8]
   0x0000000000406cfe <+14>:    movsd  xmm0,QWORD PTR [rsp-0x8]
   0x0000000000406d04 <+20>:    comisd xmm1,xmm0
   0x0000000000406d08 <+24>:    setne  al
   0x0000000000406d0b <+27>:    ret

which also fails to detect NaN, which is right according to the documented behaviour of comisd:
http://www.jaist.ac.jp/iscenter-new/mpc/altix/altixdata/opt/intel/vtune/doc/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc44.htm
Comment 5 Richard Biener 2014-02-17 12:45:57 UTC
Dup.  You can try building with -fno-builtin-isnan, but no - that's not a
"portable" way.

*** This bug has been marked as a duplicate of bug 25975 ***
Comment 6 N Schaeffer 2014-02-17 16:16:29 UTC
-fno-builtin-isnan is also interesting, thanks.

Is there somewhere a rationale for not making isnan() find NaN's with -ffinite-math-only ?
Comment 7 Marc Glisse 2014-02-17 17:28:19 UTC
(In reply to N Schaeffer from comment #6)
> Is there somewhere a rationale for not making isnan() find NaN's with
> -ffinite-math-only ?

finite-math-only is basically a promise that isinf and isnan always return false...

I have inline library functions that do: if (isnan(x)) ...
When compiled with -ffinite-math-only, I want this eliminated as dead code, that's the reason I made the function inline in the first place.

Another way to cheat:
int myisnan(double)__asm__("isnan");