Message ID | 4EB5A1C2.7090606@net-b.de |
---|---|
State | New |
Headers | show |
> The test uses the largest available floating-point number - be it 8, 10 > or 16 - and tests for that. The checks should be thus OK for any system. It fails with a link failure on SPARC Solaris 8 and 9: FAIL: gfortran.dg/quad_2.f90 -O0 (test for excess errors) Excess errors: Undefined first referenced symbol in file sqrtl /var/tmp//ccU7N9qc.o ld: fatal: Symbol referencing errors. No output written to ./quad_2.exe
On Mon, Nov 07, 2011 at 09:55:48PM +0100, Eric Botcazou wrote: > > The test uses the largest available floating-point number - be it 8, 10 > > or 16 - and tests for that. The checks should be thus OK for any system. > > It fails with a link failure on SPARC Solaris 8 and 9: > > FAIL: gfortran.dg/quad_2.f90 -O0 (test for excess errors) > Excess errors: > Undefined first referenced > symbol in file > sqrtl /var/tmp//ccU7N9qc.o > ld: fatal: Symbol referencing errors. No output written to ./quad_2.exe I suppose the obvious question is 'does libm on sparc solaris 8/9 contain a long double sqrtl() function?' If the answer is no, then xfail the testcase.
Steve Kargl <sgk@troutmask.apl.washington.edu> writes: > On Mon, Nov 07, 2011 at 09:55:48PM +0100, Eric Botcazou wrote: >> > The test uses the largest available floating-point number - be it 8, 10 >> > or 16 - and tests for that. The checks should be thus OK for any system. >> >> It fails with a link failure on SPARC Solaris 8 and 9: >> >> FAIL: gfortran.dg/quad_2.f90 -O0 (test for excess errors) >> Excess errors: >> Undefined first referenced >> symbol in file >> sqrtl /var/tmp//ccU7N9qc.o >> ld: fatal: Symbol referencing errors. No output written to ./quad_2.exe > > I suppose the obvious question is 'does libm on sparc solaris 8/9 > contain a long double sqrtl() function?' If the answer is no, > then xfail the testcase. Please no: sqrtl is a C99 addition, and we don't want lists of non-C99 targets in tests that require them. Rainer
On Tue, Nov 08, 2011 at 11:14:52AM +0100, Rainer Orth wrote: > Steve Kargl <sgk@troutmask.apl.washington.edu> writes: > > > On Mon, Nov 07, 2011 at 09:55:48PM +0100, Eric Botcazou wrote: > >> > The test uses the largest available floating-point number - be it 8, 10 > >> > or 16 - and tests for that. The checks should be thus OK for any system. > >> > >> It fails with a link failure on SPARC Solaris 8 and 9: > >> > >> FAIL: gfortran.dg/quad_2.f90 -O0 (test for excess errors) > >> Excess errors: > >> Undefined first referenced > >> symbol in file > >> sqrtl /var/tmp//ccU7N9qc.o > >> ld: fatal: Symbol referencing errors. No output written to ./quad_2.exe > > > > I suppose the obvious question is 'does libm on sparc solaris 8/9 > > contain a long double sqrtl() function?' If the answer is no, > > then xfail the testcase. > > Please no: sqrtl is a C99 addition, and we don't want lists of non-C99 > targets in tests that require them. > OK, so, then we simply accept that running a regression test on these targets will always FAIL? If the answer is 'yes', then please close this PR because I doubt anyone will implement sqrtl().
Steve Kargl <sgk@troutmask.apl.washington.edu> writes: >> Please no: sqrtl is a C99 addition, and we don't want lists of non-C99 >> targets in tests that require them. >> > > OK, so, then we simply accept that running a regression test > on these targets will always FAIL? If the answer is 'yes', > then please close this PR because I doubt anyone will implement > sqrtl(). No. AFAICS so far C99 functions have been implemented in intrinsics/c99_functions.c for the benefit of platforms that aren't C99. Has this policy changed recently? I don't think it's a good idea for libgfortran to contain references to nonexistant functions (or for gfortran to emit references to C99 functions on non-C99 platforms, if that's the case). At least that's not what any other GCC language frontend does. Rainer
On Tue, Nov 8, 2011 at 17:41, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote: > Steve Kargl <sgk@troutmask.apl.washington.edu> writes: > >>> Please no: sqrtl is a C99 addition, and we don't want lists of non-C99 >>> targets in tests that require them. >>> >> >> OK, so, then we simply accept that running a regression test >> on these targets will always FAIL? If the answer is 'yes', >> then please close this PR because I doubt anyone will implement >> sqrtl(). > > No. AFAICS so far C99 functions have been implemented in > intrinsics/c99_functions.c for the benefit of platforms that aren't > C99. Has this policy changed recently? I don't think there has ever been a such a hard policy. Yes, c99_functions.c provides _some_ C99 functions when they can be implemented in terms of other available functions. E.g. sqrtf() is provided by #ifndef HAVE_SQRTF #define HAVE_SQRTF 1 float sqrtf (float x); float sqrtf (float x) { return (float) sqrt (x); } #endif Obviously, sqrtl() could be provided in the same way using the C89 sqrt(), but I'm sure we all agree that would be a pretty crappy implementation. I think it's better to leave it out than to give users a false impression that they have a functioning sqrtl. > I don't think it's a good idea for libgfortran to contain references to > nonexistant functions (or for gfortran to emit references to C99 > functions on non-C99 platforms, if that's the case). At least that's > not what any other GCC language frontend does. So what would be a good solution then, assuming Santa doesn't suddenly provide us with a target-independent C99 math library? One solution, I suppose, would be to not support real(kind=10) (C long double) on non-C99 targets. Do we have some mechanism for determining this when building the frontend?
On Tue, Nov 08, 2011 at 04:41:32PM +0100, Rainer Orth wrote: > Steve Kargl <sgk@troutmask.apl.washington.edu> writes: > > >> Please no: sqrtl is a C99 addition, and we don't want lists of non-C99 > >> targets in tests that require them. > >> > > > > OK, so, then we simply accept that running a regression test > > on these targets will always FAIL? If the answer is 'yes', > > then please close this PR because I doubt anyone will implement > > sqrtl(). > > No. AFAICS so far C99 functions have been implemented in > intrinsics/c99_functions.c for the benefit of platforms that aren't > C99. Has this policy changed recently? The policy has not changed. However, it took me >3 years to get an implementation of sqrtl() into FreeBSD's libm. On the surface, sqrtl() looks almost trivial to implement, but the IEEE 754 requirement of correct rounding in all rounding modes can be a nightmare to get right. Adopting FreeBSD sqrtl() has some issues. > I don't think it's a good idea for libgfortran to contain references to > nonexistant functions (or for gfortran to emit references to C99 > functions on non-C99 platforms, if that's the case). At least that's > not what any other GCC language frontend does. AFAIK, gfortran has always assumed that it is being built/run on a system with C99 functions. If one does not care about correct rounding, then one can do #include <math.h> long double sqrtl(long double x) { if (x == 0) return x; if (x < 0) return ((x - x) / (x - x)); if (isfinite(x)) { reduce x to 2*f*2**n. check if x is subnormal and adjust f and n. if (n is odd) { f = 2*f; n--; } use Newtow's iteration to compute sqrtl(f) with a starting value of xn = sqrt(f) now combine everything return (xn*2**(n/2)) } else return (x * x + x); }
Index: gcc/testsuite/gfortran.dg/quad_2.f90 =================================================================== --- gcc/testsuite/gfortran.dg/quad_2.f90 (Revision 0) +++ gcc/testsuite/gfortran.dg/quad_2.f90 (Revision 0) @@ -0,0 +1,63 @@ +! { dg-do run } +! +! This test checks whether the largest possible +! floating-point number works. +! +! This is a run-time check. Depending on the architecture, +! this tests REAL(8), REAL(10) or REAL(16) and REAL(16) +! might be a hardware or libquadmath 128bit number. +! +program test_qp + use iso_fortran_env, only: real_kinds + implicit none + integer, parameter :: QP = real_kinds(ubound(real_kinds,dim=1)) + real(qp) :: fp1, fp2, fp3, fp4 + character(len=80) :: str1, str2, str3, str4 + fp1 = 1 + fp2 = sqrt (2.0_qp) + write (str1,*) fp1 + write (str2,'(g0)') fp1 + write (str3,*) fp2 + write (str4,'(g0)') fp2 + +! print '(3a)', '>',trim(str1),'<' +! print '(3a)', '>',trim(str2),'<' +! print '(3a)', '>',trim(str3),'<' +! print '(3a)', '>',trim(str4),'<' + + read (str1, *) fp3 + if (fp1 /= fp3) call abort() + read (str2, *) fp3 + if (fp1 /= fp3) call abort() + read (str3, *) fp4 + if (fp2 /= fp4) call abort() + read (str4, *) fp4 + if (fp2 /= fp4) call abort() + + select case (qp) + case (8) + if (str1 /= " 1.0000000000000000") call abort() + if (str2 /= "1.0000000000000000") call abort() + if (str3 /= " 1.4142135623730951") call abort() + if (str4 /= "1.4142135623730951") call abort() + case (10) + if (str1 /= " 1.00000000000000000000") call abort() + if (str2 /= "1.00000000000000000000") call abort() + if (str3 /= " 1.41421356237309504876") call abort() + if (str4 /= "1.41421356237309504876") call abort() + case (16) + if (str1 /= " 1.00000000000000000000000000000000000") call abort() + if (str2 /= "1.00000000000000000000000000000000000") call abort() + if (str3 /= " 1.41421356237309504880168872420969798") call abort() + if (str4 /= "1.41421356237309504880168872420969798") call abort() + block + real(qp), volatile :: fp2a + fp2a = 2.0_qp + fp2a = sqrt (fp2a) + if (abs (fp2a - fp2) > sqrt(2.0_qp)-nearest(sqrt(2.0_qp),-1.0_qp)) call abort() + end block + case default + call abort() + end select + +end program test_qp Index: gcc/testsuite/ChangeLog =================================================================== --- gcc/testsuite/ChangeLog (Revision 181014) +++ gcc/testsuite/ChangeLog (Arbeitskopie) @@ -1,3 +1,7 @@ +2011-11-05 Tobias Burnus <burnus@net-b.de> + + * gfortran.dg/quad_2.f90: New. + 2011-11-05 Eric Botcazou <ebotcazou@adacore.com> * gcc.dg/strlenopt-22g.c: New wrapper around... @@ -26,10 +30,10 @@ 2011-10-09 Magnus Fromreide <magfr@lysator.liu.se> - * g++.dg/cpp0x/enum21a.C: Test that enum x { y, } does - generate a pedwarn in c++98-mode. - * g++.dg/cpp0x/enum21b.C: Test that enum x { y, } - don't generate a pedwarn in c++0x-mode. + * g++.dg/cpp0x/enum21a.C: Test that enum x { y, } does + generate a pedwarn in c++98-mode. + * g++.dg/cpp0x/enum21b.C: Test that enum x { y, } + don't generate a pedwarn in c++0x-mode. 2011-11-04 Olivier Goffart <olivier@woboq.com>