This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] (1/3) Add back libgcc-math


On Thu, 16 Nov 2006, Kaveh R. GHAZI wrote:

> On Thu, 16 Nov 2006, Joseph S. Myers wrote:
> 
> > The glibc tests should be useful as a source of (presumed correct) inputs
> > and outputs (once you remove cases involving denormals and other special
> > values).  Another possible source would be the tests Kaveh's been using to
> > verify the builtins using MPFR.
> 
> That would be:
> http://www.inf.ethz.ch/personal/gonnet/FPAccuracy/Analysis.html
> 
> Thanks go to Roger for discovering it.

Nice.  For example running it on the vectorized sin we get

lower part of the vector:

result of sin is never more precise than double

37 results were exact to double the precision

20 largest ulp errors (stored in a double)
   0.55905 ulp for sin(-0.900233182999999881) = -0.783471837206970334)
   0.55766 ulp for sin(-9.91922716649999714) = 0.474546897516641697)
   0.54253 ulp for sin(457.554096816759511) = -0.899415577157950508)
   0.54085 ulp for sin(-9.91922716649995451) = 0.474546897516604171)
   0.53627 ulp for sin(383.965456880003899) = 0.637426115021635931)
   0.53283 ulp for sin(8.53027063300001132) = 0.779900810743759609)
   0.53050 ulp for sin(376.094201957056271) = -0.781406438005402326)
   0.53030 ulp for sin(376.094201960000987) = -0.781406436167833229)
   0.52989 ulp for sin(466.053110759998503) = 0.890024100458920886)
   0.52414 ulp for sin(0.686114334800000059) = 0.633535580623448391)
   0.52330 ulp for sin(-0.587555582999999992) = -0.554328197237298093)
   0.52244 ulp for sin(-0.875010530199999748) = -0.767550252018587953)
   0.51852 ulp for sin(-9.70787900720002561) = 0.279334592539650539)
   0.51630 ulp for sin(481.257804540000109) = -0.55978684409342172)
   0.51549 ulp for sin(7.06292111799999667) = 0.703091578995210353)
   0.51423 ulp for sin(-9.79246416090000515) = 0.359457247014940307)
   0.51394 ulp for sin(-0.789293982800000626) = -0.709856168518460895)
   0.51338 ulp for sin(-9.86851377109996797) = 0.429316465552575188)
   0.51279 ulp for sin(5.59905335500030077) = -0.632000540472898109)
   0.51244 ulp for sin(0.686114334799999059) = 0.633535580623447503)

<tr><td align=left><a href=sin.res>sin</a></td><td 
align=right>1257</td><td 
align=right>0.55905</td><td>-0.900233182999999881</td><td>-0.783471837206970334</td></tr>


upper part of the vector (I just was curious):

result of sin is never more precise than double

37 results were exact to double the precision

20 largest ulp errors (stored in a double)
   0.55905 ulp for sin(-0.900233182999999881) = -0.783471837206970334)
   0.55766 ulp for sin(-9.91922716649999714) = 0.474546897516641697)
   0.54253 ulp for sin(457.554096816759511) = -0.899415577157950508)
   0.54085 ulp for sin(-9.91922716649995451) = 0.474546897516604171)
   0.53627 ulp for sin(383.965456880003899) = 0.637426115021635931)
   0.53283 ulp for sin(8.53027063300001132) = 0.779900810743759609)
   0.53050 ulp for sin(376.094201957056271) = -0.781406438005402326)
   0.53030 ulp for sin(376.094201960000987) = -0.781406436167833229)
   0.52989 ulp for sin(466.053110759998503) = 0.890024100458920886)
   0.52414 ulp for sin(0.686114334800000059) = 0.633535580623448391)
   0.52330 ulp for sin(-0.587555582999999992) = -0.554328197237298093)
   0.52244 ulp for sin(-0.875010530199999748) = -0.767550252018587953)
   0.51852 ulp for sin(-9.70787900720002561) = 0.279334592539650539)
   0.51630 ulp for sin(481.257804540000109) = -0.55978684409342172)
   0.51549 ulp for sin(7.06292111799999667) = 0.703091578995210353)
   0.51423 ulp for sin(-9.79246416090000515) = 0.359457247014940307)
   0.51394 ulp for sin(-0.789293982800000626) = -0.709856168518460895)
   0.51338 ulp for sin(-9.86851377109996797) = 0.429316465552575188)
   0.51279 ulp for sin(5.59905335500030077) = -0.632000540472898109)
   0.51244 ulp for sin(0.686114334799999059) = 0.633535580623447503)

<tr><td align=left><a href=sin.res>sin</a></td><td 
align=right>1257</td><td 
align=right>0.55905</td><td>-0.900233182999999881</td><td>-0.783471837206970334</td></tr>


One could try to provide a customized trailer.h that deals with vector
input/output and arbitrarily combines input values into the upper and
lower halves of the vector (I just filled in zero for the other part
in the above tests).  I.e. my setup for sin.c was to change it like

--- sin.c       2002-09-01 19:04:09.000000000 +0200
+++ sinv.c      2006-11-16 16:21:02.000000000 +0100
@@ -4,7 +4,9 @@
 #include "header.h"
 #define DBL_MAX_EXP 1024
 #define N 1257
-#define F sin
+typedef double __v2df __attribute__ ((__vector_size__ (16)));
+extern __v2df __vrd2_sin (__v2df);
+#define F(x) __builtin_ia32_vec_ext_v2df(__vrd2_sin((__v2df){ 0, x }), 1)
 #define Fs "sin"
 
 struct input_point { double arg_m, val, eps;

(this is the diff for using the upper half).


For exp we get

result of exp is never more precise than double

3 results were exact to double the precision

20 largest ulp errors (stored in a double)
   0.86632 ulp for exp(-705.497170525292404) = 4.04084174858101023e-307)
   0.68467 ulp for exp(1.00000000000000022) = 2.71828182845904553)
   0.64596 ulp for exp(0.999999999999999889) = 2.71828182845904465)
   0.63111 ulp for exp(316.37732952000016) = 2.51726194186815054e+137)
   0.60938 ulp for exp(706.919974728539273) = 1.02670144153346535e+307)
   0.59335 ulp for exp(481.257804540000961) = 1.01767448152262847e+209)
   0.57860 ulp for exp(416.244840379999857) = 5.92703235123047658e+180)
   0.57086 ulp for exp(-704.578700682763724) = 1.01241419771917072e-306)
   0.56899 ulp for exp(706.197466014038923) = 4.98497086000417386e+306)
   0.56889 ulp for exp(-704.132863269264021) = 1.58118598189173931e-306)
   0.56826 ulp for exp(708.147269211793514) = 3.50309079335330967e+307)
   0.56535 ulp for exp(7.08347321750000436) = 1192.1017652344342)
   0.56330 ulp for exp(447.928298940000445) = 3.4102680633389404e+194)
   0.56153 ulp for exp(709.134919829994146) = 9.40551557807151211e+307)
   0.55960 ulp for exp(-707.765602322764039) = 4.18123358656724449e-308)
   0.55912 ulp for exp(706.344066931938755) = 5.77205676702844896e+306)
   0.55758 ulp for exp(709.134919829826913) = 9.40551557649859635e+307)
   0.55753 ulp for exp(494.794769700000018) = 7.70261436591727699e+214)
   0.55726 ulp for exp(0.981195265500000136) = 2.66764287861071381)
   0.55626 ulp for exp(-707.691345968795076) = 4.5035351325229914e-308)

<tr><td align=left><a href=exp.res>exp</a></td><td 
align=right>1333</td><td 
align=right>0.86632</td><td>-705.497170525292404</td><td>4.04084174858101023e-307</td></tr>


for log we have

result of log is never more precise than double

1 results were exact to double the precision

20 largest ulp errors (stored in a double)
   0.51150 ulp for log(0.598293376600000149) = -0.513674049013464806)
   0.50457 ulp for log(0.845871897600000699) = -0.167387352117867594)
   0.50364 ulp for log(0.542851097299999696) = -0.610920218937617276)
   0.50358 ulp for log(0.916959415999986649) = -0.0866920650660323033)
   0.50341 ulp for log(0.55800374090000604) = -0.583389612501424071)
   0.50293 ulp for log(0.430561392099999607) = -0.842665358777628271)
   0.50290 ulp for log(0.206222208499999976) = -1.57880100951316127)
   0.50279 ulp for log(0.843057167399999252) = -0.170720509044688329)
   0.50210 ulp for log(0.836344301099995358) = -0.178714907260612343)
   0.50170 ulp for log(5.79735296150004142) = 1.75740142742834049)
   0.50157 ulp for log(6.40799246450000748) = 1.85754603381343264)
   0.50111 ulp for log(0.207535839100006336) = -1.57245123567126877)
   0.50105 ulp for log(5.6574311444999017) = 1.73296992779305681)
   0.50104 ulp for log(0.558003740899994827) = -0.583389612501444166)
   0.50100 ulp for log(0.190575456500002016) = -1.65770706572826265)
   0.50098 ulp for log(0.430561392099992724) = -0.842665358777644258)
   0.50076 ulp for log(358.449485859985202) = 5.88178774595550458)
   0.50074 ulp for log(9.5314451135008369) = 2.2545963445228363)
   0.50071 ulp for log(0.84305716740000447) = -0.170720509044682139)
   0.50068 ulp for log(1.64872127070014929) = 0.500000000000012879)

<tr><td align=left><a href=log.res>log</a></td><td 
align=right>1135</td><td 
align=right>0.51150</td><td>0.598293376600000149</td><td>-0.513674049013464806</td></tr>


All pretty well, but I don't know what kind of inputs the test uses
(does it at all check things like signed zeros, and Infs and NaNs?)

It also does not provide float variants, so I could not test __vrs4_powf
(there's no __vrd2_pow, as the required quad-precision fallback is not
available there - __vrs4_powf fails back to using __vrd4_exp and
__vrd4_log in some cases to achieve the required precision).

The results look pretty ok to me.

Richard.

--
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]