Date: Tue, 28 May 2013 01:12:12 -0700 From: David Schultz <das@freebsd.org> To: Bruce Evans <brde@optusnet.com.au> Cc: Diane Bruce <db@db.net>, John Baldwin <jhb@freebsd.org>, David Chisnall <theraven@freebsd.org>, Stephen Montgomery-Smith <stephen@missouri.edu>, freebsd-numerics@freebsd.org, Bruce Evans <bde@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: <20130528081212.GA13594@zim.MIT.EDU> In-Reply-To: <20130528150808.F1298@besplex.bde.org> 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>
next in thread | previous in thread | raw e-mail | index | archive | help
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! > % 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 @@ > % .... > % +#pragma STDC FENV_ACCESS ON > % +#pragma STDC CX_LIMITED_RANGE OFF > > Heheh, style rules for #pragma. I like the old rule which says that > it should be indented 6 feet under. It is still almost useless, since > we don't even have any C99 compilers than implement the fenv pragmas > yet. They are mostly just there to document the fact that this code is expecting FENV_ACCESS to work. Clang, adding insult to injury, generates a warning about these. I don't think they're going to implement the missing C99 features soon. Many bugs have been filed about the issue, but I haven't heard of any progress. When I asked years ago, I was basically told that the LLVM IR can't support the feature without substantial modifications. > % + * 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. 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) }, }; int i; for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { testall_tol(cacos, tests[i].z, tests[i].acos_z, 2); testall_odd_tol(casin, tests[i].z, tests[i].asin_z, 2); testall_odd_tol(catan, tests[i].z, tests[i].atan_z, 2); } A few more tests would be good (e.g., large inputs, parts of the range that are close to an axis or discontinuity), but I ran out of time. > 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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130528081212.GA13594>