On 29 Jul 2013, at 08:05, David Schultz <d...@freebsd.org> wrote: > On Thu, Jul 11, 2013, David Chisnall wrote: >> +static __inline int >> +__inline_isnan(double __x) >> +{ >> + >> + return (__x != __x); >> +} >> + >> +static __inline int >> +__inline_isnanf(float __x) >> +{ >> + >> + return (__x != __x); >> +} >> + >> +static __inline int >> +__inline_isnanl(long double __x) >> +{ >> + >> + return (__x != __x); >> +} > > This has already been covered at greater length, but I believe > this part is incorrect. Relational operators can raise an invalid > exception when one of the arguments is a NaN -- even a quiet NaN. > Raising an exception is optional in C99 (7.12.14) and required in > IEEE-754... in practice, it tends to be platform- and compiler- > specific. > > That is the whole reason the is* macros are defined by the > standard in the first place, and also why we didn't use the > trivial implementation above. The is* macros are required to not > raise an exception.
What would you suggest replacing them with? Note that currently LLVM iR doesn't provide any way of distinguishing the != comparison from something that is guaranteed not to raise an exception. I don't know how this works in GIMPLE, althouhg I'd imagine that, since gcc has a working Fortran front end, there is some better support for it. > P.S. It would be great if clang implemented the FENV_ACCESS pragma > and provided an intrinsic that produced a fast inline isnan() when > the pragma is off, and the full, correct one when the pragma is on. I almost agree, but C is a really terrible language for mathematical work and I'd prefer that people just used Fortran instead of trying to force C to be Fortran. In particular, take a look in the C11 spec for the semantics of this: _Atomic(double) x = ...; x += 1; It's quite astonishingly horrible. We don't implement it correctly in clang, and I hope never to have to. David
signature.asc
Description: Message signed with OpenPGP using GPGMail