Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 May 2013 20:47:45 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        David Schultz <das@FreeBSD.org>
Cc:        Diane Bruce <db@db.net>, Bruce Evans <brde@optusnet.com.au>, John Baldwin <jhb@FreeBSD.org>, David Chisnall <theraven@FreeBSD.org>, Stephen Montgomery-Smith <stephen@missouri.edu>, freebsd-numerics@FreeBSD.org, Steve Kargl <sgk@troutmask.apl.washington.edu>, Peter Jeremy <peter@rulingia.com>, Warner Losh <imp@bsdimp.com>
Subject:   Re: Use of C99 extra long double math functions after r236148
Message-ID:  <20130528195733.Q2294@besplex.bde.org>
In-Reply-To: <20130528081212.GA13594@zim.MIT.EDU>
References:  <501204AD.30605@missouri.edu> <20120727032611.GB25690@server.rulingia.com> <20120728125824.GA26553@server.rulingia.com> <501460BB.30806@missouri.edu> <20120728231300.GA20741@server.rulingia.com> <50148F02.4020104@missouri.edu> <20120729222706.GA29048@server.rulingia.com> <5015BB9F.90807@missouri.edu> <20130528043205.GA3282@zim.MIT.EDU> <20130528150808.F1298@besplex.bde.org> <20130528081212.GA13594@zim.MIT.EDU>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 28 May 2013, David Schultz wrote:

> On Tue, May 28, 2013, Bruce Evans wrote:
>> @ diff -u2 catrigl.c~ catrigl.c
>> @ --- catrigl.c~	2012-09-22 21:14:24.000000000 +0000
>> @ +++ catrigl.c	2013-05-26 08:46:10.423187000 +0000
>> @ @@ -50,4 +50,6 @@
>> @  #define signbit(x)	(__builtin_signbitl(x))
>> @
>> @ +long double atanhl(long double);
>> @ +
>> @  static const long double
>> @  A_crossover =		10,
>>
>> catrigl.c depends on atanhl(), logl() and log1pl() existing.
>
> Yep, I'm ignoring the complex long double functions until the real
> long double functions are done. I'm hoping that won't be too long!

As usual, you can find my current versions in
~bde/msun/src/zztest/s_log*.c, ~bde/msun/src/zztest/ld128/s_logl.c,
and ~bde/msun/src/zztest/cplex.c (clog*).  Lots of macros in
~bde/msun/src/zztest/math_private.h are also needed.  The header needs
more cleaning than the C files, but you can easily extract the parts
needed.

>> % Index: tools/regression/lib/msun/test-invctrig.c
>> % ===================================================================
>> % --- tools/regression/lib/msun/test-invctrig.c	(revision 0)
>> % +++ tools/regression/lib/msun/test-invctrig.c	(working copy)
>> % @@ -0,0 +1,467 @@
>> % ....
>
>> % + * XXX gcc implements complex multiplication incorrectly. In
>> % + * particular, it implements it as if the CX_LIMITED_RANGE pragma
>> % + * were ON. Consequently, we need this function to form numbers
>> % + * such as x + INFINITY * I, since gcc evalutes INFINITY * I as
>> % + * NaN + INFINITY * I.
>> % + */
>> % +static inline long double complex
>> % +cpackl(long double x, long double y)
>> % +{
>> % +	long double complex z;
>> % +
>> % +	__real__ z = x;
>> % +	__imag__ z = y;
>> % +	return (z);
>> % +}
>>
>> Why duplicate this?  I guess it is because math_private,h is hard to
>> include.  I use complicated conditionals (mostly switches on
>> $(uname -p) and $(hostname) in shell scripts to locate it when
>> compiling from external directories.
>
> I will change to CMPLXL, now that CMPLXL has been committed.
> Thanks for reminding me.

That won't be very portable.  I already need ifdefs and extra code in
math_private.h to restore the old version that works with old versions
of gcc.

> The ability to use complex numbers in
> initializers is nice (ignore whitespace munging due to cut/paste):
>
>        static const struct {
>                complex long double z;
>                complex long double acos_z;
>                complex long double asin_z;
>                complex long double atan_z;
>        } tests[] = {
>                { CMPLXL(0.75L, 0.25L),
>                  CMPLXL(pi / 4, -0.34657359027997265470861606072908828L),
>                  CMPLXL(pi / 4, 0.34657359027997265470861606072908828L),
>                  CMPLXL(0.66290883183401623252961960521423782L,
>                         0.15899719167999917436476103600701878L) },
>        };

I think you mean "nasty" :-).  Simply x + I * y seems to work correctly
with the following compilers on amd64: gcc-2.95.4, gcc-3.3.3, gcc-3.4.6,
gcc-4.2.1, clang 3.3.
    But you cannot use either x + I * y or CMPLXL() with literals for
    for for long doubles, since on i386 most of the gcc's will round the
    long doubles to 53 bits, so you must use LD80C() for most long double
    constants, and LD80C() won't work inside either x + I * y or CMPLXL().

I didn't test this with exactly the above.  Untested conversion of it:

                { 0.75L +  I * 0.25L,
                  pi / 4 + I * -0.34657359027997265470861606072908828L,
                  pi / 4 + I *  0.34657359027997265470861606072908828L,
                  0.66290883183401623252961960521423782L +
                           I * 0.15899719167999917436476103600701878L, },

Is pi a variable, and/or does CMPLXL() work with variables in static
initializers?  Non-static initializers and CMPLXL() can be used on
variables constructed using LD80C().  Now gcc-3.3.3 generates horrible
code for a runtime evaluation and probably causes overflow bugs for
exceptional args (the ones that we invented cpack*() to avoid).  gcc-4.2.1
generates good code.  The freebsd cluster seems to have crashed while I
was writing this, so I don't have access to the other compilers.

>> The tests seem to be compiled with -O0.  That tests a different
>> environment than the usual runtime one, and in particular misses seeing
>> most precision bugs.  I mostly test with -O (-O2 with gcc is slower
>> and even harder to debug, while with clang it makes little difference),
>> but switch to -O0 to debug.  -g -O is now almost unusable because -O
>> optimizes away dead variables and -g is broken in many cases (sometimes
>> it can't even show live variables).
>
> I want the tests to come as close as possible to testing the
> behavior that real programs will see. Unfortunately, any test that
> exercises different rounding modes or looks at floating-point
> exceptions is pretty much doomed to fail with gcc and clang, so I
> gave up. (Sometimes I wonder if there's any point in having a free
> library that supports them if you need a commercial compiler to
> take advantage.) However, the tests do sometimes uncover compiler
> bugs that get fixed. They caught a few bugs in gcc builtins, and
> an arithmetic bug in clang's constant-folding code, all of which
> were fixed.

But doesn't using -O0 give the opposite of that?  The library is closer
to working than tests and real programs since it is relatively careful
and the compiler problems usually don't have much effect (since wrong
rounding by the compiler tends to show up as errors of >= 1 ulp and
gets fixed).

Bruce



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