From owner-svn-src-all@FreeBSD.ORG Sun Nov 11 16:53:54 2012 Return-Path: Delivered-To: svn-src-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id D02D81884; Sun, 11 Nov 2012 16:53:54 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from fallbackmx09.syd.optusnet.com.au (fallbackmx09.syd.optusnet.com.au [211.29.132.242]) by mx1.freebsd.org (Postfix) with ESMTP id 2D3528FC6B; Sun, 11 Nov 2012 16:47:40 +0000 (UTC) Received: from mail03.syd.optusnet.com.au (mail03.syd.optusnet.com.au [211.29.132.184]) by fallbackmx09.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id qABGldOO014943; Mon, 12 Nov 2012 03:47:39 +1100 Received: from c122-106-175-26.carlnfd1.nsw.optusnet.com.au (c122-106-175-26.carlnfd1.nsw.optusnet.com.au [122.106.175.26]) by mail03.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id qABGlSUq005809 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 12 Nov 2012 03:47:30 +1100 Date: Mon, 12 Nov 2012 03:47:28 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Dimitry Andric Subject: Re: svn commit: r242879 - in head/lib: libc/gen msun/src In-Reply-To: <509FC025.9070703@FreeBSD.org> Message-ID: <20121112024108.W1858@besplex.bde.org> References: <201211102122.qAALMAnO014246@svn.freebsd.org> <20121110214345.GT73505@kib.kiev.ua> <509ED25E.3070302@FreeBSD.org> <20121111230817.G1155@besplex.bde.org> <509FC025.9070703@FreeBSD.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-Cloudmark-Score: 0 X-Optus-Cloudmark-Analysis: v=2.0 cv=JdTkNj2V c=1 sm=1 a=3cd0u8GmRs4A:10 a=kj9zAlcOel0A:10 a=PO7r1zJSAAAA:8 a=JzwRw_2MAAAA:8 a=4PLq0TcHr_4A:10 a=pcNIaovmKlT530XI9BEA:9 a=CjuIK1q_8ugA:10 a=bxQHXO5Py4tHmhUgaywp5w==:117 Cc: Konstantin Belousov , svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, Bruce Evans 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: Sun, 11 Nov 2012 16:53:54 -0000 On Sun, 11 Nov 2012, Dimitry Andric wrote: > On 2012-11-11 14:07, Bruce Evans wrote: >> ... >> The pessimality of these functions is another problem. C99 only requires >> ... >> - if you compile isnan*(x) calls using gcc _without_ including , >> then you get annoying (and broken) warnings about implicit function >> declarations being invalid in C99. This is a bug in clang. These >> functions are reserved in C99, so some other warning for them would >> be correct, but things warning is wrong in several ways: >> - implicit function declarations are not invalid in C9 > > Implicit function declarations are invalid in C99, not in C89. Clang > defaults to C99. Whether the function is reserved or not, should not > matter. > >> - the same warning is printed for -ffreestanding, but these functions >> are not reserved by C99 then. > > Again, I don't agree. Reserved or not is not relevant. If the above > reasoning was followed, we would never have to include either, > because all those prototypes would already be implicitly there? :-) Oops, I thought it was removed later. >> After turning off the broken warning using >> -Wno-implicit-function-declarations, everything works right for these >> function calls, but of course not for others for which you want this >> warning. >> So for clang you must include for calling these functions, > > No, according to the C99 standard you must include . Quoting > 7.12.3.4: > > Synopsis: > > #include > int isnan(real-floating x); > > The synopses of all math functions explicitly have the the #include at > the top. Except with -ffreestanding, isnan() is not reserved and might not exist. gcc and clang handle this correctly by not converting isnan*() into a builtin. >> [... isnan() gets turned into an extern function that bypasses better >> builtins] > In short, maybe just: > > #define isnan __builtin_isnan > > ? That should cover all cases. With a fallback for !gcc && !clang, > obviously. The functions stay behind for backwards compatibility. This fails for gcc-3.3.3 which I test on (gcc-3.3.3 produces better libm code in some cases). >> Fixing the pessimizations would reduce the ABI problems. Both libc >> and libm should translate to the builtin if it exists and is a real >> builtin (not a libcall). This seems reasonable even without -O, since >> C99 doesn't require any functions to exist so nothing should take their >> addresses or try to call them as non-macros ('(isnan)(x)'). >> already has complications to use builtins for 1 set of interfaces only. >> The only problems are that it is that it is hard to tell if builtins >> exist and are real (there are compiler predefines for the set that >> uses builtins but not for most sets). > > How is it hard to tell? Both gcc and clang support those builtins, > unless you want to support very old versions of gcc, which might not > have them. It is easy to hard-code ifdefs on the compiler name, but only for a couple of compiler/version combinations, and this is ugly. Then there is the problem that some builtins just gives libcalls so they are useless. In general, whether a builtin gives a libcall is MD. __builtin_fma() should be an example. It should give hardware fma on ia64 but doesn't. It should give hardware fma on any future x86 that has fma. Currently it always gives a libcall so it is useless. >> With this, the library functions are never used by new compiles and >> are only needed by old applications. All static copies of them can >> be removed, but the .so ones are still needed until the ABI is changed. >> >> When will the library isnanf() have been deprecated long enough to >> remove in .so's too? Maybe it never needed to be preserved, since >> old applications will link to old libraries that have it. > > I don't think we can ever remove them from libc.so anymore, unless > version bumps are reintroduced. :-) Sigh, the version has been bumped twice since isnanf() was deprecated. First from 5 to 6 in 2004 just 3 months days after the deprecation. Then from 6 to 7 in 2006. The log message says that isnan() and others are done in the "hard" way instead of relying on fpclassify(), for binary compatibility since we have never bumpled libm's major number, but that has also been bumped twice since the deprecation. Using fpclassify() would actually be the hard way for isnan(), since there is no builtin for it. Of the functions referred to in the log message, isinf() is easy using its builtin and isfinite() and isnormal() are "hard" since they don't have a builtin in gcc. Summary of the libm builtins: - isnan(): good but not always used - isinf(): like isnan() - isfinite(): only in clang (I don't know if it is more than a libcall) - isnormal(): like isfinite() - signbit(): like isnan() - significand(): only in gcc, and seems to be just a libcall. This one is a nonstandard old-IEEE API while the others are C99. - fma(): builtin but useless since it is always (?) a libcall. - sin(), cos(), ...: only in clang, and useless since they are libcalls at best. clang seems to have builtins that expand to libcalls for most libc and libm functions. Bruce