This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
RE: Macros using __NO_LONG_DOUBLE_MATH
- From: "Wilco Dijkstra" <wdijkstr at arm dot com>
- To: "'Joseph Myers'" <joseph at codesourcery dot com>
- Cc: "GNU C Library" <libc-alpha at sourceware dot org>
- Date: Mon, 8 Jun 2015 13:31:35 +0100
- Subject: RE: Macros using __NO_LONG_DOUBLE_MATH
- Authentication-results: sourceware.org; auth=none
- References: <000801d09eb7$48f0aa80$dad1ff80$ at com> <alpine dot DEB dot 2 dot 10 dot 1506041456390 dot 12011 at digraph dot polyomino dot org dot uk>
> Joseph Myers wrote:
> On Thu, 4 Jun 2015, Wilco Dijkstra wrote:
>
> > Hi,
> >
> > Looking at math/math.h, a common idiom is:
> >
> > # ifdef __NO_LONG_DOUBLE_MATH
> > # define isnan(x) \
> > (sizeof (x) == sizeof (float) ? __isnanf (x) : __isnan (x))
> > # else
> > # define isnan(x) \
> > (sizeof (x) == sizeof (float) \
> > ? __isnanf (x) \
> > : sizeof (x) == sizeof (double) \
> > ? __isnan (x) : __isnanl (x))
> > # endif
> >
> > This looks unnecessary - given that it is OK to use the double version when
> > __NO_LONG_DOUBLE_MATH is defined, sizeof (long double) == sizeof (double)
> > when long double math is not supported. Also sysdeps/ieee754/ldbl-opt
> > defines all the long double functions using double, so even we did accidentally
> > expand into __isnanl, it would be the same as __isnan anyway.
> So no __isnanl declaration is generally visible in the
> __NO_LONG_DOUBLE_MATH case if _LIBC, preventing a definition using
> __isnanl from being used.
Thanks for the detailed explanation - it looks like if we agree on always
inlining in GLIBC then we can remove it.
> I don't see how such a change would benefit using GCC built-in functions
> anyway. Presumably you'd do
>
> # if __GNUC_PREREQ (6, 0)
I'm using __GNUC_PREREQ (4, 4) && !defined __SUPPORT_SNAN__ to enable inlining -
better to have inlining even if it isn't 100% optimal rather than no inlining
and having to go through the PLT to call a 4-instruction function...
> # define isnan(x) __builtin_isnan (x)
> # elif defined __NO_LONG_DOUBLE_MATH
> ...
> # else
> ...
> # endif
>
> if GCC 6 is the version for which you fix __builtin_isnan to be
> universally usable including in the signaling NaN case, or something more
> complicated if you want to handle older GCC versions as well - but in any
> case, the new cases can just go before the existing ones. Note that:
>
> (a) All these GCC built-in functions, except for __builtin_signbit (GCC
> bug 36757), are type-generic (which is good for avoiding the expansion
> text containing the argument text more than once). (But depending on the
> conditions under which such functions are used, watch out for some having
> been added in earlier GCC versions than they became type-generic.)
GCC4.4 added isinf_sign etc and explicitly documents them as type generic.
> (b) You'd only use the GCC built-in functions when guaranteed to expand
> inline rather than to an external function call - so, when using them, you
> don't need to worry about whether the corresponding external function
> exists or not.
They are always inlined, even with -O0 and fno-builtin.
However what to do with the odd 128-bit IBM long double format? Is it dead
or still used? Currently __copysignl uses the builtin internally which would
only update one of the 2 signs... If GCC doesn't understand the format then
isinf, isnormal, isfinite would likely be incorrect as well as these need
the right LDBL_MIN/MAX value.
Wilco