From owner-svn-src-all@FreeBSD.ORG Sat Jul 13 19:54:44 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 90424EF; Sat, 13 Jul 2013 19:54:44 +0000 (UTC) (envelope-from tijl@coosemans.org) Received: from mailrelay006.isp.belgacom.be (mailrelay006.isp.belgacom.be [195.238.6.172]) by mx1.freebsd.org (Postfix) with ESMTP id 7F2B61E41; Sat, 13 Jul 2013 19:54:43 +0000 (UTC) X-Belgacom-Dynamic: yes X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmEGADyw4VFR8aPm/2dsb2JhbABagwbCYIEIF3SCIwEBBAFWIgEFCwsOCgkWDwkDAgECASceBg0BBQIBAYgGCrYaj2QHg3gDkA+BLZdtgxQ6 Received: from 230.163-241-81.adsl-dyn.isp.belgacom.be (HELO kalimero.tijl.coosemans.org) ([81.241.163.230]) by relay.skynet.be with ESMTP; 13 Jul 2013 21:54:30 +0200 Received: from kalimero.tijl.coosemans.org (kalimero.tijl.coosemans.org [127.0.0.1]) by kalimero.tijl.coosemans.org (8.14.7/8.14.7) with ESMTP id r6DJsSDs003538; Sat, 13 Jul 2013 21:54:29 +0200 (CEST) (envelope-from tijl@coosemans.org) Message-ID: <51E1B06E.2010300@coosemans.org> Date: Sat, 13 Jul 2013 21:54:22 +0200 From: Tijl Coosemans User-Agent: Mozilla/5.0 (X11; FreeBSD i386; rv:17.0) Gecko/20130701 Thunderbird/17.0.7 MIME-Version: 1.0 To: Bruce Evans Subject: Re: svn commit: r253215 - head/lib/msun/src References: <201307111741.r6BHf5gQ060844@svn.freebsd.org> <51DEFEF7.4080709@coosemans.org> <7D521907-4802-4141-9A5E-40EB157A5AEF@FreeBSD.org> <51DF0FA5.4050106@coosemans.org> <51DF14F9.50001@coosemans.org> <20130712180753.E5131@besplex.bde.org> In-Reply-To: <20130712180753.E5131@besplex.bde.org> X-Enigmail-Version: 1.5.1 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="----enig2AURBEBSHXJSPFJCLLSSL" Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, David Chisnall X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Jul 2013 19:54:44 -0000 This is an OpenPGP/MIME signed message (RFC 4880 and 3156) ------enig2AURBEBSHXJSPFJCLLSSL Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On 2013-07-12 11:14, Bruce Evans wrote: > On Thu, 11 Jul 2013, Tijl Coosemans wrote: >> On 2013-07-11 22:03, Tijl Coosemans wrote: >>> On 2013-07-11 21:36, David Chisnall wrote: >>>> On 11 Jul 2013, at 19:52, Tijl Coosemans wrote:= >>>>>> @@ -227,8 +250,6 @@ double expm1(double); >>>>>> double fma(double, double, double); >>>>>> double hypot(double, double); >>>>>> int ilogb(double) __pure2; >>>>>> -int (isinf)(double) __pure2; >>>>>> -int (isnan)(double) __pure2; >>>>> >>>>> I think they should stay for the C90 case. >>>> >>>> That would completely defeat the point of this entire exercise and b= e >>>> redundant unless we aim to support a compiler that only supports C90= >>>> and no GNU extensions, in which case you'll hit errors in cdefs.h, >>>> long before you get to this point in an include. >>> >>> isnan(double) is part of SUSv2. It should be visible when compiling w= ith >>> -D_XOPEN_SOURCE=3D500. I think you need something like this: >>>=20 >>> #if (__BSD_VISIBLE || __XSI_VISIBLE <=3D 500) && __ISO_C_VISIBLE < 19= 99 >>> int isinf(double) __pure2; >>> int isnan(double) __pure2; >>> #endif >> >> Actually this: >> >> #if (__BSD_VISIBLE || (defined(__XSI_VISIBLE) && __XSI_VISIBLE <=3D 50= 0)) >> && __ISO_C_VISIBLE < 1999 >=20 > Remove the __ISO_C_VISIBLE part, since this is not in C90. This also > fixes a style bug (long line). I shouldn't have mentioned C90. What I meant to say is the not-C99-or-higher case which is further restricted by __BSD_VISIBLE and __XSI_VISIBLE, but where the macros aren't defined. These two symbols are the cause for the original problem report about clang's cmath header (in C++11 isnan/isinf are functions returning bool not int). Their visibility had to be constrained somehow and that cascaded into redefining the isnan and isinf macros because they were implemented using these functions. I think completely removing these symbols is wrong however because it breaks the API in the specific case of the #if above. If __ISO_C_VISIBLE < 1999 isn't correct then maybe __cplusplus < 201103L?= > How can that work? Even you forgot to restore the parentheses around > the functions, so the above has syntax errors. The macros aren't there for __ISO_C_VISIBLE < 1999. > I noticed some more problems in the implementation of these macros > and others: > - many or all of the __pure2's in the prototypes are wrong, since even > the classification functions can have side effects for signaling > NaNs. It is impossible to avoid these side effects for extern > functions in some cases, since the ABI gives them. I think static > inline functions must have the same results as extern functions, > so compilers should pessimize inline functions as necessary to > get the same bad results, but compilers don't do that. Apparently, in the 2008 version of IEEE 754 they are considered non-computational and never generate exceptions, even for sNaN. The old IEEE 754-1985 only mentions isfinite and isnan and says implementations may consider them non-arithmetic. > - classification functions are specified to convert to the semantic > type (remove any extra precision or exponent range) before classifyin= g. Yes, it makes the macros more function-like. > For example, if x is a double slightly larger than sqrt(DBL_MAX), and= > if double expressions are evaluated in extra exponent range, then x*x= > is finite with the extra range but infinite in the semantic type. So= > isinf(x*x) is true, and the implementation > #define isinf(x) (fabs(x) =3D=3D INFINITY) is invalid. clang on x86 = gets > __builtin_isinf(x*x) this right as a side effect of its pessimization= > of fabs() to non-inline -- parameter passing to the extern fabs() > converts to the semantic type. Sometimes the arg is known not to hav= e > extra range, so no conversion is needed. If isinf isn't supposed to generate exceptions then it cannot use a floating point comparison either. That would only leave bit operations. > I think C11 has new mistakes for extra precision. It specifies that > return reduces to the semantic type, like the classification macros > are required to do for their arg. clang -std=3Dc11 doesn't implement > this bug for at least: >=20 > #include > double sq(double x) { return (x*x); } > double sq2(double x) { return (fabs(x*x); } >=20 > On i386 without SSE2 (so extra precision), this generates the same code= > as with -std=3Dc99. Squaring x gives extra precision and exponent rang= e. > This is not destroyed on return, so extra precision is not defeated by > writing the squaring operation as a function. fabs() is inlined in bot= h > cases, so it has little effect here (no effect unless x is NaN), but I > think even C99 doesn't permit this. If fabs() were not inline, then > the ABI would force destruction of the extra precision and range when > it is called, and I think C99 requires conversion to the semantic type > for calls. For function parameters both C99 and C11 state that they are converted as if by assignment meaning extra precision should be removed. This is also required by IEEE 754-2008. Both C99 and C11 state that making a function inline suggests calls to the function should be as fast as possible, but I don't think this allows skipping any conversions so even if a function is inlined the compiler should remove extra precision. If a floating point value already has the right precision then assignment and as-if-by-assignment may be seen as copy operations that don't raise any exceptions even for sNaN. I suppose this means math functions must always use each argument in at least one arithmetic operation to trigger sNaNs. For return statements both C99 and C11 state that it's not an assignment. Only if the type of the return expression differs from the return type is the result converted as if by assignment. There's a footnote that says this allows floating point values to be returned with extra precision if there's no conversion. The extra precision can be removed with a cast. IEEE 754-2008 requires that extra precision is removed. Also, fabs is somewhat special. In IEEE 754-1985 it's considered equal to copysign(x, 1.0) which may but doesn't have to raise exceptions even for sNaN. In IEEE 754-2008, operations that only affect the sign, like fabs, don't raise exceptions. ------enig2AURBEBSHXJSPFJCLLSSL Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.20 (FreeBSD) iF4EAREIAAYFAlHhsHQACgkQfoCS2CCgtitQAQD+JsZOKK4gl9sxZg+Yd/rkPw21 7+7O07oJ+IcNPo0VEJUBAIMLkZUomXOFd0te6ScwU3qMi9Zrk5WPOqZZE/zeDXpE =1iBY -----END PGP SIGNATURE----- ------enig2AURBEBSHXJSPFJCLLSSL--