Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Nov 2012 03:47:28 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Dimitry Andric <dim@FreeBSD.org>
Cc:        Konstantin Belousov <kostikbel@gmail.com>, svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, Bruce Evans <brde@optusnet.com.au>
Subject:   Re: svn commit: r242879 - in head/lib: libc/gen msun/src
Message-ID:  <20121112024108.W1858@besplex.bde.org>
In-Reply-To: <509FC025.9070703@FreeBSD.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>

next in thread | previous in thread | raw e-mail | index | archive | help
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 <math.h>,
>>     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 <stdio.h> 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 <math.h> for calling these functions,
>
> No, according to the C99 standard you must include <math.h>.  Quoting
> 7.12.3.4:
>
>  Synopsis:
>
>  #include <math.h>
>  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 <math.h> 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)').  <math.h>
>> 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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20121112024108.W1858>