From owner-svn-src-head@FreeBSD.ORG Tue Jul 30 07:02:31 2013 Return-Path: Delivered-To: svn-src-head@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 1DC0D93B; Tue, 30 Jul 2013 07:02:31 +0000 (UTC) (envelope-from das@FreeBSD.org) Received: from zim.MIT.EDU (50-196-151-174-static.hfc.comcastbusiness.net [50.196.151.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 012FA2702; Tue, 30 Jul 2013 07:02:30 +0000 (UTC) Received: from zim.MIT.EDU (localhost [127.0.0.1]) by zim.MIT.EDU (8.14.7/8.14.2) with ESMTP id r6U72Nc8077397; Tue, 30 Jul 2013 00:02:23 -0700 (PDT) (envelope-from das@FreeBSD.org) Received: (from das@localhost) by zim.MIT.EDU (8.14.7/8.14.2/Submit) id r6U72NAj077396; Tue, 30 Jul 2013 00:02:23 -0700 (PDT) (envelope-from das@FreeBSD.org) Date: Tue, 30 Jul 2013 00:02:23 -0700 From: David Schultz To: David Chisnall Subject: Re: svn commit: r253215 - head/lib/msun/src Message-ID: <20130730070223.GA74642@zim.MIT.EDU> References: <201307111741.r6BHf5gQ060844@svn.freebsd.org> <20130729070517.GA3192@zim.MIT.EDU> <00F2B647-8D25-45FB-B852-5214AC27AD26@FreeBSD.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <00F2B647-8D25-45FB-B852-5214AC27AD26@FreeBSD.org> Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 30 Jul 2013 07:02:31 -0000 On Mon, Jul 29, 2013, David Chisnall wrote: > On 29 Jul 2013, at 08:05, David Schultz 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. I'm not sure what the inlines here were supposed to achieve, but I think the ideal implementation would be a compiler intrinsic, with a fallback of the libm functions if there's no working compiler support. As I recall, gcc has a __builtin_isnan() and macros to test whether __builtin_nan() exists. Presumably it wouldn't be too hard to do the same thing in clang. > > 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. Fortran has its own problems and isn't very well supported. But for what it's worth, C++ is actually a good choice for high-performance numerics, IMO, mainly because of operator overloading and generics. I can write a function that looks like actual math, and call it with a float, a double, or even an arbitrary-precision mpfr_t, and it just works. In C, on the other hand, they added all this "type-generic arithmetic" and complex number nonsense that's of very limited interest. In a better language, that functionality could have been implemented as a third-party library instead of as a built-in part of the language. So in that sense, I agree with you that C went too far with trying to compete with Fortran... FENV_ACCESS is more reasonable, though. It basically says that sophisticated users ought to be able to take advantage of the IEEE floating-point features that nearly all hardware FPUs support, without having the compiler mess things up. Meanwhile, there's a second mode for users who don't care, where the optimizer is allowed to make a lot more assumptions. Before C99, compilers tended to have some muddled combination of the two extremes, which is bad for everyone. Unfortunately, only the commercial compilers actually implement FENV_ACCESS these days... > 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. I hope it does something horrible to the programmer who thought of the idea of atomic double-precision arithmetic.