summaryrefslogtreecommitdiffstats
path: root/lib/msun/src
Commit message (Collapse)AuthorAgeFilesLines
...
* On arches where long double is the same as double, alias ceil(), floor()bde2008-02-133-0/+12
| | | | | | | and trunc() to the corresponding long double functions. This is not just an optimization for these arches. The full long double functions have a wrong value for `huge', and the arches without full long doubles depended on it being wrong.
* Fix the C version of ceill(x) for -1 < x <= -0 in all rounding modes.bde2008-02-131-1/+1
| | | | The result should be -0, but was +0.
* Fix exp2*(x) on signaling NaNs by returning x+x as usual.bde2008-02-132-2/+2
| | | | | | | | | | | | | | | This has the side effect of confusing gcc-4.2.1's optimizer into more often doing the right thing. When it does the wrong thing here, it seems to be mainly making too many copies of x with dependency chains. This effect is tiny on amd64, but in some cases on i386 it is enormous. E.g., on i386 (A64) with -O1, the current version of exp2() should take about 50 cycles, but took 83 cycles before this change and 66 cycles after this change. exp2f() with -O1 only speeded up from 51 to 47 cycles. (exp2f() should take about 40 cycles, on an Athlon in either i386 or amd64 mode, and now takes 42 on amd64). exp2l() with -O1 slowed down from 155 cycles to 123 for some args; this is unimportant since the i386 exp2l() is a fake; the wrong thing for it seems to involve branch misprediction.
* Rearrange the polynomial evaluation for better parallelism. This isbde2008-02-131-3/+4
| | | | | | | | | | | | | | faster on all machines tested (old Celeron (P2), A64 (amd64 and i386) and ia64) except on ia64 when compiled with -O1. It takes 2 more multiplications, so it will be slower on old machines. The speedup is about 8 cycles = 17% on A64 (amd64 and i386) with best CFLAGS and some parallelism in the caller. Move the evaluation of 2**k up a bit so that it doesn't compete too much with the new polynomial evaluation. Unlike the previous optimization, this rearrangement cannot change the result, so compilers and CPU schedulers can do it, but they don't do it quite right yet. This saves a whole 1 or 2 cycles on A64.
* Fix remainder() and remainderf() in round-towards-minus-infinity modebde2008-02-122-8/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | when the result is +-0. IEEE754 requires (in all rounding modes) that if the result is +-0 then its sign is the same as that of the first arg, but in round-towards-minus-infinity mode an uncorrected implementation detail always reversed the sign. (The detail is that x-x with x's sign positive gives -0 in this mode only, but the algorithm assumed that x-x always has positive sign for such x.) remquo() and remquof() seem to need the same fix, but I cannot test them yet. Use long doubles when mixing NaN args. This trick improves consistency of results on at least amd64, so that more serious problems like the above aren't hidden in simple regression tests by noise for the NaNs. On amd64, hardware remainder should be used since it is about 10 times faster than software remainder and is already used for remquo(), but it involves using the i387 even for floats and doubles, and the i387 does NaN mixing which is better than but inconsistent with SSE NaN mixing. Software remainder() would probably have been inconsistent with software remainderl() for the same reason if the latter existed. Signaling NaNs cause further inconsistencies on at least ia64 and i386. Use __FBSDID().
* Use double precision for z and thus for the entire calculation ofbde2008-02-111-3/+4
| | | | | | | | | | | | | | | | | | | | exp2(i/TBLSIZE) * p(z) instead of only for the final multiplication and addition. This fixes the code to match the comment that the maximum error is 0.5010 ulps (except on machines that evaluate float expressions in extra precision, e.g., i386's, where the evaluation was already in extra precision). Fix and expand the comment about use of double precision. The relative roundoff error from evaluating p(z) in non-extra precision was about 16 times larger than in exp2() because the interval length is 16 times smaller. Its maximum was at least P1 * (1.0 ulps) * max(|z|) ~= log(2) * 1.0 * 1/32 ~= 0.0217 ulps (1.0 ulps from the addition in (1 + P1*z) with a cancelation error when z ~= -1/32). The actual final maximum was 0.5313 ulps, of which 0.0303 ulps must have come from the additional roundoff error in p(z). I can't explain why the additional roundoff error was almost 3/2 times larger than the rough estimate.
* As usual, use a minimax polynomial that is specialized for floatbde2008-02-091-7/+8
| | | | | | | | | | | | | | | | | | | | | | | precision. The new polynomial has degree 4 instead of 10, and a maximum error of 2**-30.04 ulps instead of 2**-33.15. This doesn't affect the final error significantly; the maximum error was and is about 0.5015 ulps on i386 -O1, and the number of cases with an error of > 0.5 ulps is increased from 13851 to 14407. Note that the error is only this close to 0.5 ulps due to excessive extra precision caused by compiler bugs on i386. The extra precision could be obtained intentionally, and is useful for keeping the error of the hyperbolic float functions below 1 ulp, since these functions are implemented using expm1f. My recent change for scaling by 2**k had the unintentional side effect of retaining extra precision for longer, so callers of expm1f see errors of more like 0.0015 ulps than 0.5015 ulps, and for the hyperbolic functions this reduces the maximum error from nearly about 2 ulps to about 0.75 ulps. This is about 10% faster on i386 (A64). expm1* is still very slow, but now the float version is actually significantly faster. The algorithm is very sophisticated but not very good except on machines with fast division.
* Fix a comment about coefficients and expand a related one.bde2008-02-091-2/+2
|
* Fix truncl() when the result should be -0.0L. When the result is +-0.0L,bde2008-02-081-1/+2
| | | | | it must have the same sign as the arg in all rounding modes, but it was always +0.0L.
* Oops, fix the fix in rev.1.10. logb() and logbf() were broken onbde2008-02-081-5/+4
| | | | | | | denormals, and logb() remained broken after 1.10 because the fix for logbf() was incompletely translated. Convert to __FBSDID().
* Use a better method of scaling by 2**k. Instead of adding to thebde2008-02-072-26/+16
| | | | | | | | | | | | | | | | | | | | | | | | exponent bits of the reduced result, construct 2**k (hopefully in parallel with the construction of the reduced result) and multiply by it. This tends to be much faster if the construction of 2**k is actually in parallel, and might be faster even with no parallelism since adjustment of the exponent requires a read-modify-wrtite at an unfortunate time for pipelines. In some cases involving exp2* on amd64 (A64), this change saves about 40 cycles or 30%. I think it is inherently only about 12 cycles faster in these cases and the rest of the speedup is from partly-accidentally avoiding compiler pessimizations (the construction of 2**k is now manually scheduled for good results, and -O2 doesn't always mess this up). In most cases on amd64 (A64) and i386 (A64) the speedup is about 20 cycles. The worst case that I found is expf on ia64 where this change is a pessimization of about 10 cycles or 5%. The manual scheduling for plain exp[f] is harder and not as tuned. Details specific to expm1*: - the saving is closer to 12 cycles than to 40 for expm1* on i386 (A64). For some reason it is much larger for negative args. - also convert to __FBSDID().
* Use a better method of scaling by 2**k. Instead of adding to thebde2008-02-074-33/+28
| | | | | | | | | | | | | | | | | | | | | exponent bits of the reduced result, construct 2**k (hopefully in parallel with the construction of the reduced result) and multiply by it. This tends to be much faster if the construction of 2**k is actually in parallel, and might be faster even with no parallelism since adjustment of the exponent requires a read-modify-wrtite at an unfortunate time for pipelines. In some cases involving exp2* on amd64 (A64), this change saves about 40 cycles or 30%. I think it is inherently only about 12 cycles faster in these cases and the rest of the speedup is from partly-accidentally avoiding compiler pessimizations (the construction of 2**k is now manually scheduled for good results, and -O2 doesn't always mess this up). In most cases on amd64 (A64) and i386 (A64) the speedup is about 20 cycles. The worst case that I found is expf on ia64 where this change is a pessimization of about 10 cycles or 5%. The manual scheduling for plain exp[f] is harder and not as tuned. This change ld128/s_exp2l.c has not been tested.
* As for the float trig functions and logf, use a minimax polynomialbde2008-02-061-6/+7
| | | | | | | | | | | | | that is specialized for float precision. The new polynomial has degree 5 instead of 11, and a maximum error of 2**-27.74 ulps instead of 2**-30.64. This doesn't affect the final error significantly; the maximum error was and is about 0.9101 ulps on amd64 -01 and the number of cases with an error of > 0.5 ulps is actually reduced by epsilon despite the larger error in the polynomial. This is about 15% faster on amd64 (A64), i386 (A64) and ia64. The asm version is still used instead of this on i386 since it is faster and more accurate.
* Adjust the exponent before converting the result from double todas2008-01-281-16/+10
| | | | | float precision. This fixes some double rounding problems for subnormals and simplifies things a bit.
* Fix a harmless type error in 1.9.bde2008-01-251-1/+1
|
* Fix cutoffs. This is just a cleanup and an optimization for unusualbde2008-01-211-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | cases which are used mainly by regression tests. As usual, the cutoff for tiny args was not correctly translated to float precision. It was 2**-54 but 2**-24 works. It must be about 2**-precision, since the error from approximating log(1+x) by x is about the same as |x|. Exhaustive testing shows that 2**-24 gives perfect rounding in round-to-nearest mode. Similarly for the cutoff for being small, except this is not used by so many other functions. It was 2**-29 but 2**-15 works. It must be a bit smaller than sqrt(2**-precision), since the error from approximating log(1+x) by x-x*x/2 is about the same as x*x. Exhaustive testing shows that 2**-15 gives a maximum error of 0.5052 ulps in round-to-nearest-mode. The algorithm for the general case is only good for 0.8388 ulps, so this is sufficient (but it loses slightly on i386 -- then extra precision gives 0.5032 ulps for the general case). While investigating this, I noticed that optimizing the usual case by falling into a middle case involving a simple polynomial evaluation (return x-x*x/2 instead of x here) is not such a good idea since it gives an enormous pessimization of tinier args on machines for which denormals are slow. Float x*x/2 is denormal when |x| ~< 2**-64 and x*x/2 is evaluated in float precision, so it can easily be denormal for normal x. This is even more interesting for general polynomial evaluations. Multiplying out large powers of x is normally a good optimization since it reduces dependencies, but it creates denormals starting with quite large x.
* Oops, when merging from the float version to the double versions, don'tbde2008-01-201-1/+1
| | | | | | | | | forget to translate "float" to "double". ucbtest didn't detect the bug, but exhaustive testing of the float case relative to the double case eventually did. The bug only affects args x with |x| ~> 2**19*(pi/2) on non-i386 (i386 is broken in a different way for large args).
* Remove the float version of the kernel of arg reduction for pi/2, sincebde2008-01-191-198/+0
| | | | | | | it should never have existed and it has not been used for many years (floats are reduced faster using doubles). All relevant changes (just the workaround for broken assignment) have been merged to the double version.
* Do an ordinary assignment in STRICT_ASSIGN() except for floats untilbde2008-01-191-2/+6
| | | | | | | | | there is a problem with non-floats (when i386 defaults to extra precision). This essentially restores yesterday's behaviour for doubles on i386 (since generic rint() isn't used and everywhere else assumed working assignment), but for arches that use the generic rint() it finishes restoring some of 1995's behaviour (don't waste time doing unnecessary store/load).
* Use STRICT_ASSIGN() for exp2f() and exp2() instead of a volatilebde2008-01-192-4/+5
| | | | | | | | | | | | | | | | | | | variable hack for exp2f() only. The volatile variable had a surprisingly large cost for exp2f() -- 19 cycles or 15% on i386 in the worst case observed. This is only partly explained by there being several references to the variable, only one of which benefited from it being volatile. Arches that have working assignment are likely to benefit even more from not having any volatile variable. exp2() now has a chance of working with extra precision on i386. exp2() has even more references to the variable, so it would have been pessimized more by simply declaring the variable as volatile. Even the temporary volatile variable for STRICT_ASSIGN costs 5-10% on i386, (A64) so I will change STRICT_ASSIGN() to do an ordinary assignment until i386 defaults to extra precision.
* Use STRICT_ASSIGN() for _kernel_rem_pio2f() and _kernel_rem_pio2f()bde2008-01-192-7/+10
| | | | | | | | | | | | instead of a volatile cast hack for the float version only. The cast hack broke with gcc-4, but this was harmless since the float version hasn't been used for a few years. Merge from the float version so that the double version has a chance of working on i386 with extra precision. See k_rem_pio2f.c rev.1.8 for the original hack. Convert to _FBSDID().
* Use STRICT_ASSIGN() for log1pf() and log1p() instead of a volatile castbde2008-01-192-8/+10
| | | | | | | | | | | | | | hack for log1pf() only. The cast hack broke with gcc-4, resulting in ~1 million errors of more than 1 ulp, with a maximum error of ~1.5 ulps. Now the maximum error for log1pf() on i386 is 0.5034 ulps again (this depends on extra precision), and log1p() has a chance of working with extra precision. See s_log1pf.c 1.8 for the original hack. (It claims only 62343 large errors). Convert to _FBSDID(). Another thing broken with gcc-4 is the static const hack used for rcsids.
* Use STRICT_ASSIGN() instead of assorted direct volatile hacks to workbde2008-01-192-6/+8
| | | | | | | | | | | | | | | | | | around assignments not working for gcc on i386. Now volatile hacks for rint() and rintf() don't needlessly pessimize so many arches and the remaining pessimizations (for arm and powerpc) can be avoided centrally. This cleans up after s_rint.c 1.3 and 1.13 and s_rintf.c 1.3 and 1.9: - s_rint.c 1.13 broke 1.3 by only using a volatile cast hack in 1 place when it was needed in 2 places, and the volatile cast hack stopped working with gcc-4. These bugs only affected correctness tests on i386 since i386 normally uses asm rint() and doesn't support the extra precision mode that would break assignments of doubles. - s_rintf.c 1.9 improved(?) on 1.3 by using a volatile variable hack instead of an extra-precision variable hack, but it declared 2 variables as volatile when only 1 variable needed to be volatile. This only affected speed tests on i386 since i386 uses asm rintf().
* Use volatile hacks to make sure these functions generate an underflowdas2008-01-183-3/+6
| | | | | exception when they're supposed to. Previously, gcc -O2 was optimizing away the statement that generated it.
* Implement exp2l(). There is one version for machines with 80-bitdas2008-01-182-0/+8
| | | | | | | | long doubles (i386, amd64, ia64) and one for machines with 128-bit long doubles (sparc64). Other platforms use the double version. I've only done runtime testing on i386. Thanks to bde@ for helpful discussions and bugfixes.
* Add a macro STRICT_ASSIGN() to help avoid the compiler bug thatbde2008-01-171-0/+16
| | | | | | | | | | | | | assignments and casts don't clip extra precision, if any. The implementation is to assign to a temporary volatile variable and read the result back to assign to the original lvalue. lib/msun currently 2 different hard-coded hacks to avoid the problem in just a few places and needs it in a few more places. One variant uses volatile for the original lvalue. This works but is slower than necessary. Another temporarily casts the lvalue to volatile. This broke with gcc-4.2.1 or earlier (gcc now stores to the lvalue but doesn't load from it).
* Optimize this a bit better.das2008-01-151-13/+18
| | | | Submitted by: bde (although these aren't all of his changes)
* Implement rintl(), nearbyintl(), lrintl(), and llrintl().das2008-01-146-5/+105
| | | | Thanks to bde@ for feedback and testing of rintl().
* - Correct the range check in the double version to catch negative valuesdas2008-01-112-19/+22
| | | | | that would overflow. - Style fixes and improved handling of NaNs suggested by bde.
* Grumble. DO declare logbl(), DON'T declare logl() just yet.das2007-12-201-0/+2
| | | | | | | bde is going to commit logl() Real Soon Now. I'm just trying to slow him down with merge conflicts. Noticed by: bde
* Remove the declaration of logl(). The relevant bits haven't beendas2007-12-201-2/+0
| | | | | | | committed yet, but the declaration leaked in when I added nan() and friends. Reported by: pav
* Since nan() is supposed to work the same as strtod("nan(...)", NULL),das2007-12-182-18/+67
| | | | | | | | | | | | my original implementation made both use the same code. Unfortunately, this meant libm depended on a vendor header at compile time and previously- unexposed vendor bits in libc at runtime. Hence, I just wrote my own version of the relevant vendor routine. As it turns out, mine has a factor of 8 fewer of lines of code, and is a bit more readable anyway. The strtod() and *scanf() routines still use vendor code. Reviewed by: bde
* Remove z_abs(). The z_*() functions were in libf77, and for some reasondas2007-12-181-7/+0
| | | | | | | | someone thought it would be a good idea to copy z_abs() to libm in 1994. However, it's never been declared or documented anywhere, and I'm reasonably confident that nobody uses it. Discussed with: bde, deischen, kan
* Add logbl(3) to libm.das2007-12-172-0/+61
|
* Implement and document nan(), nanf(), and nanl(). This commitdas2007-12-162-1/+71
| | | | | | | adds two new directories in msun: ld80 and ld128. These are for long double functions specific to the 80-bit long double format used on x86-derived architectures, and the 128-bit format used on sparc64, respectively.
* Implement and document csqrt(3) and csqrtf(3).das2007-12-152-0/+192
|
* Implement carg(3) and cargf(3).das2007-12-122-0/+76
| | | | Rotting in an old src tree since: March 2005
* Oops, back out previous commit since it was backwards to a wrong branch.bde2007-06-141-1/+1
|
* MFC: 1.11: fix the threshold for (not) using the simple Taylor approximation.bde2007-06-141-1/+1
|
* Fix an aliasing bug which was finally detected by gcc-4.2. fdlibm hasbde2007-06-111-1/+1
| | | | | | | | | hundreds of similar aliasing bugs, but all except this one seem to have been fixed by Cygnus and/or NetBSD before the modified version of fdlibm was imported into FreeBSD in 1994. PR: standards/113147 Submitted by: Steve Kargl <sgk@troutmask.apl.washington.edu>
* Merge the relevant part of rev.1.14 of s_cbrt.c (a micro-optimizationbde2007-05-291-3/+3
| | | | | | involving moving the check for x == 0). The savings in cycles are smaller for cbrtf() than for cbrt(), and positive in all measured cases with gcc-3.4.4, but still very machine/compiler-dependent.
* Don't assume that int is signed 32-bits in one place. Keep assumingbde2007-05-022-8/+11
| | | | | | | | | | | | | | that ints have >= 31 value bits elsewhere. s/int/int32_t/ seems to have been done too globally for all other files in msun/src before msun/ was imported into FreeBSD. Minor fixes in comments. e_lgamma_r.c: Describe special cases in more detail: - exception for lgamma(0) and lgamma(neg.integer) - lgamma(-Inf) = Inf. This is wrong but is required by C99 Annex F. I hope to change this.
* Implement modfl().das2007-01-072-1/+102
|
* Correctly handle NaN.das2007-01-061-0/+2
|
* Correctly handle inf/nan. This routine is currently unused because wedas2007-01-061-0/+4
| | | | | seem to have assembly versions for all architectures, but it can't hurt to fix it.
* Fixed the threshold for using the simple Taylor approximation.bde2006-07-072-2/+2
| | | | | | | | | | | | | | | | | | | | | In e_log.c, there was just a off-by-1 (1 ulp) error in the comment about the threshold. The precision of the threshold is unimportant, but the magic numbers in the code are easier to understand when the threshold is described precisely. In e_logf.c, mistranslation of the magic numbers gave an off-by-1 (1 * 16 ulps) error in the intended negative bound for the threshold and an off-by-7 (7 * 16 ulps) error in the intended positive bound for the threshold, and the intended bounds were not translated from the double precision bounds so they were unnecessarily small by a factor of about 2048. The optimization of using the simple Taylor approximation for args near a power of 2 is dubious since it only applies to a relatively small proportion of args, but if it is done then doing it 2048 times as often _may_ be more efficient. (My benchmarks show unexplained dependencies on the data that increase with further optimizations in this area.)
* Fixed tanh(-0.0) on ia64 and optimizeed tanh(x) for 2**-55 <= |x| <bde2006-07-051-10/+10
| | | | | | | | | | | | | | | | | | | 2**-28 as a side effect, by merging with the float precision version of tanh() and the double precision version of sinh(). For tiny x, tanh(x) ~= x, and we used the expression x*(one+x) to return this value (x) and set the inexact flag iff x != 0. This doesn't work on ia64 since gcc -O does the dubious optimization x*(one+x) = x+x*x so as to use fma, so the sign of -0.0 was lost. Instead, handle tiny x in the same as sinh(), although this is imperfect: - return x directly and set the inexact flag in a less efficient way. - increased the threshold for non-tinyness from 2**-55 to 2**-28 so that many more cases are optimized than are pessimized. Updated some comments and fixed bugs in others (ranges for half-open intervals mostly had the open end backwards, and there were nearby style bugs).
* Backed out rev.1.10. It tried to implement ldexpf() as a weak referencebde2006-07-051-2/+0
| | | | | | | | | | | | | | | | | to scalbf(), but ldexpf() cannot be implemented in that way since the types of the second parameter differ. ldexpf() can be implemented as a weak or strong reference to scalbnf() (*) but that was already done long before rev.1.10 was committed. The old implementation uses a reference, so rev.1.10 had no effect on applications. The C files for the scalb() family are not used for amd64 or i386, so rev.1.10 had even less effect for these arches. (*) scalbnf() raises the radix to the given exponent, while ldexpf() raises 2 to the given exponent. Thus the functions are equivalent except possibly for their error handling iff the radix is 2. Standards more or less require identical error handling. Under FreeBSD, the functions are equivalent except for more details being missing in scalbnf()'s man page.
* Oops, on amd64 (and probably on all non-i386 systems), the previousbde2006-01-051-6/+11
| | | | | | | | | | | | | | commit broke the 2**24 cases where |x| > DBL_MAX/2. There are exponent range problems not just for denormals (underflow) but for large values (overflow). Doubles have more than enough exponent range to avoid the problems, but I forgot to convert enough terms to double, so there was an x+x term which was sometimes evaluated in float precision. Unfortunately, this is a pessimization with some combinations of systems and compilers (it makes no difference on Athlon XP's, but on Athlon64's it gives a 5% pessimization with gcc-3.4 but not with gcc-3.3). Exlain the problem better in comments.
* Use double precision internally to optimize cbrtf(), and change thebde2006-01-051-28/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | algorithm for the second step significantly to also get a perfectly rounded result in round-to-nearest mode. The resulting optimization is about 25% on Athlon64's and 30% on Athlon XP's (about 25 cycles out of 100 on the former). Using extra precision, we don't need to do anything special to avoid large rounding errors in the third step (Newton's method), so we can regroup terms to avoid a division, increase clarity, and increase opportunities for parallelism. Rearrangement for parallelism loses the increase in clarity. We end up with the same number of operations but with a division reduced to a multiplication. Using specifically double precision, there is enough extra precision for the third step to give enough precision for perfect rounding to float precision provided the previous steps are accurate to 16 bits. (They were accurate to 12 bits, which was almost minimal for imperfect rounding in the old version but would be more than enough for imperfect rounding in this version (9 bits would be enough now).) I couldn't find any significant time optimizations from optimizing the previous steps, so I decided to optimize for accuracy instead. The second step needed a division although a previous commit optimized it to use a polynomial approximation for its main detail, and this division dominated the time for the second step. Use the same Newton's method for the second step as for the third step since this is insignificantly slower than the division plus the polynomial (now that Newton's method only needs 1 division), significantly more accurate, and simpler. Single precision would be precise enough for the second step, but doesn't have enough exponent range to handle denormals without the special grouping of terms (as in previous versions) that requires another division, so we use double precision for both the second and third steps.
OpenPOWER on IntegriCloud