#
07cc7ea7 |
| 25-Jun-2024 |
Ryan Libby <rlibby@FreeBSD.org> |
libmsun: remove duplicates after cdefs.h added inline to __always_inline
Reviewed by: kib, olce Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D45712
|
Revision tags: release/14.1.0 |
|
#
e75a1bbc |
| 23-Apr-2024 |
Karl Tomlinson <karlt+@karlt.net> |
pow,powf(3),__ieee754_rem_pio2(f): Avoid negative integer left shift UB
A compiler clever enough to know that z is positive with a non-zero biased exponent could, for example, optimize away the scal
pow,powf(3),__ieee754_rem_pio2(f): Avoid negative integer left shift UB
A compiler clever enough to know that z is positive with a non-zero biased exponent could, for example, optimize away the scalbnf(z,n) in pow() because behavior for left shift of negative values is undefined. `n` is negative when y*log2(|x|) < -0.5. i.e. |x^y| < sqrt(0.5)
The intended behavior for operator<< in this code is to shift the two's complement representation of the first operand.
In the pow() functions, the result is added to the IEEE 754 exponent of z = 2^y'. n may be negative enough to underflow the biased IEEE 754 exponent below zero, which is manifested in the sign bit of j (which would correspond to the IEEE 754 sign bit).
The conversion from uint32_t to int32_t for out-of-int32_t-range values is implementation defined. The assumed behavior of interpreting the uint32_t value as a two's complement representation of a signed value is already assumed in many parts of the code, such as uses of GET_FLOAT_WORD() with signed integers.
This code passes all the current tests, and makes some out of tree fuzzing tests pass again rather than hit UB (detailed in the commentary of the pull request).
Signed-off-by: Karl Tomlinson <karlt+@karlt.net> Reviewed by: imp, steve kargl, dim Pull Request: https://github.com/freebsd/freebsd-src/pull/1137
show more ...
|
Revision tags: release/13.3.0 |
|
#
0dd5a560 |
| 28-Jan-2024 |
Steve Kargl <kargl@FreeBSD.org> |
lib/msun: Cleanup after $FreeBSD$ removal
Remove no longer needed explicit inclusion of sys/cdefs.h.
PR: 276669 MFC after: 1 week
|
Revision tags: release/14.0.0 |
|
#
1d386b48 |
| 16-Aug-2023 |
Warner Losh <imp@FreeBSD.org> |
Remove $FreeBSD$: one-line .c pattern
Remove /^[\s*]*__FBSDID\("\$FreeBSD\$"\);?\s*\n/
|
Revision tags: release/13.2.0, release/12.4.0, release/13.1.0, release/12.3.0, release/13.0.0, release/12.2.0, release/11.4.0, release/12.1.0, release/11.3.0, release/12.0.0 |
|
#
27aa8442 |
| 20-Jul-2018 |
Bruce Evans <bde@FreeBSD.org> |
Centralize the complications for special efficient rounding to integers.
This was open-coded in range reduction for trig and exp functions. Now there are 3 static inline functions rnint[fl]() that
Centralize the complications for special efficient rounding to integers.
This was open-coded in range reduction for trig and exp functions. Now there are 3 static inline functions rnint[fl]() that replace open-coded expressions, and type-generic irint() and i64rint() macros that hide the complications for efficiently using non-generic irint() and irintl() functions and casts.
Special details:
ld128/e_rem_pio2l.h needs to use i64rint() since it needs a 46-bit integer result. Everything else only needs a (less than) 32-bit integer result so uses irint().
Float and double cases now use float_t and double_t locally instead of STRICT_ASSIGN() to avoid bugs in extra precision.
On amd64, inline asm is now only used for irint() on long doubles. The SSE asm for irint() on amd64 only existed because the ifdef tangles made the correct method of simply casting to int for this case non-obvious.
show more ...
|
Revision tags: release/11.2.0, release/10.4.0, release/11.1.0, release/11.0.1, release/11.0.0, release/10.3.0, release/10.2.0, release/10.1.0, release/9.3.0, release/10.0.0, release/9.2.0, release/8.4.0, release/9.1.0 |
|
#
e477abf7 |
| 27-Nov-2012 |
Alexander Motin <mav@FreeBSD.org> |
MFC @ r241285
|
#
a10c6f55 |
| 11-Nov-2012 |
Neel Natu <neel@FreeBSD.org> |
IFC @ r242684
|
#
23090366 |
| 04-Nov-2012 |
Simon J. Gerraty <sjg@FreeBSD.org> |
Sync from head
|
#
24bf3585 |
| 04-Sep-2012 |
Gleb Smirnoff <glebius@FreeBSD.org> |
Merge head r233826 through r240095.
|
#
f049a6cb |
| 11-Aug-2012 |
Dimitry Andric <dim@FreeBSD.org> |
Add __always_inline to __ieee754_rem_pio2() and __ieee754_rem_pio2f(), since some older versions of gcc refuse to inline these otherwise.
Requested by: bde MFC after: 1 week
|
#
2b795b29 |
| 11-Aug-2012 |
Dimitry Andric <dim@FreeBSD.org> |
Change a few extern inline functions in libm to static inline, since they need to refer to static constants, which C99 does not allow for extern inline functions.
While here, change a comment in e_r
Change a few extern inline functions in libm to static inline, since they need to refer to static constants, which C99 does not allow for extern inline functions.
While here, change a comment in e_rem_pio2f.c to mention the correct number of bits.
Reviewed by: bde MFC after: 1 week
show more ...
|
Revision tags: release/8.3.0_cvs, release/8.3.0, release/9.0.0, release/7.4.0_cvs, release/8.2.0_cvs, release/7.4.0, release/8.2.0, release/8.1.0_cvs, release/8.1.0, release/7.3.0_cvs, release/7.3.0, release/8.0.0_cvs, release/8.0.0 |
|
#
10b3b545 |
| 17-Sep-2009 |
Dag-Erling Smørgrav <des@FreeBSD.org> |
Merge from head
|
#
7d4b968b |
| 17-Sep-2009 |
Dag-Erling Smørgrav <des@FreeBSD.org> |
Merge from head up to r188941 (last revision before the USB stack switch)
|
#
7e857dd1 |
| 12-Jun-2009 |
Oleksandr Tymoshenko <gonzo@FreeBSD.org> |
- Merge from HEAD
|
#
2e03f452 |
| 04-Jun-2009 |
Jung-uk Kim <jkim@FreeBSD.org> |
Resync with head.
|
#
b492f289 |
| 03-Jun-2009 |
Ed Schouten <ed@FreeBSD.org> |
Use ISO C99 style inline semantics in msun.
Because we use ISO C99 nowadays, we can just get rid of enforcing GNU89-style inlining.
|
Revision tags: release/7.2.0_cvs, release/7.2.0 |
|
#
bad3b688 |
| 18-Jan-2009 |
Oleksandr Tymoshenko <gonzo@FreeBSD.org> |
Sync with head
|
#
4630140c |
| 13-Jan-2009 |
David Schultz <das@FreeBSD.org> |
Use __gnu89_inline so that these files will compile with newer versions of gcc, where the meaning of 'inline' was changed to match C99.
Noticed by: rdivacky
|
Revision tags: release/7.1.0_cvs, release/7.1.0, release/6.4.0_cvs, release/6.4.0 |
|
#
941ab616 |
| 08-Aug-2008 |
David Schultz <das@FreeBSD.org> |
Remove some unused variables.
Reported by: Intel C Compiler
|
#
a278d990 |
| 28-Feb-2008 |
Bruce Evans <bde@FreeBSD.org> |
Fix and improve some magic numbers for the "medium size" case.
e_rem_pio2.c: This case goes up to about 2**20pi/2, but the comment about it said that it goes up to about 2**19pi/2.
It went too far
Fix and improve some magic numbers for the "medium size" case.
e_rem_pio2.c: This case goes up to about 2**20pi/2, but the comment about it said that it goes up to about 2**19pi/2.
It went too far above 2**pi/2, giving a multiplier fn with 21 significant bits in some cases. This would be harmful except for a numerical accident. It happens that the terms of the approximation to pi/2, when rounded to 33 bits so that multiplications by 20-bit fn's are exact, happen to be rounded to 32 bits so multiplications by 21-bit fn's are exact too, so the bug only complicates the error analysis (we might lose a bit of accuracy but have bits to spare).
e_rem_pio2f.c: The bogus comment in e_rem_pio2.c was copied and the code was changed to be bug-for-bug compatible with it, except the limit was made 90 ulps smaller than necessary. The approximation to pi/2 was not modified except for discarding some of it.
The same rough error analysis that justifies the limit of 2**20pi/2 for double precision only justifies a limit of 2**18pi/2 for float precision. We depended on exhaustive testing to check the magic numbers for float precision. More exaustive testing shows that we can go up to 2**28pi/2 using a 53+25 bit approximation to pi/2 for float precision, with a the maximum error for cosf() and sinf() unchanged at 0.5009 ulps despite the maximum error in rem_pio2f being ~0.25 ulps. Implement this.
show more ...
|
#
e822ea5b |
| 25-Feb-2008 |
Bruce Evans <bde@FreeBSD.org> |
Inline __ieee754__rem_pio2f(). On amd64 (A64) and i386 (A64), this gives an average speedup of about 12 cycles or 17% for 9pi/4 < |x| <= 2**19pi/2 and a smaller speedup for larger x, and a small spe
Inline __ieee754__rem_pio2f(). On amd64 (A64) and i386 (A64), this gives an average speedup of about 12 cycles or 17% for 9pi/4 < |x| <= 2**19pi/2 and a smaller speedup for larger x, and a small speeddown for |x| <= 9pi/4 (only 1-2 cycles average, but that is 4%).
Inlining this is less likely to bust caches than inlining the float version since it is much smaller (about 220 bytes text and rodata) and has many fewer branches. However, the float version was already large due to its manual inlining of the branches and also the polynomial evaluations.
show more ...
|
#
c32951b1 |
| 25-Feb-2008 |
Bruce Evans <bde@FreeBSD.org> |
Use a temporary array instead of the arg array y[] for calling __kernel_rem_pio2(). This simplifies analysis of aliasing and thus results in better code for the usual case where __kernel_rem_pio2()
Use a temporary array instead of the arg array y[] for calling __kernel_rem_pio2(). This simplifies analysis of aliasing and thus results in better code for the usual case where __kernel_rem_pio2() is not called. In particular, when __ieee854_rem_pio2[f]() is inlined, it normally results in y[] being returned in registers. I couldn't get this to work using the restrict qualifier.
In float precision, this saves 2-3% in most cases on amd64 and i386 (A64) despite it not being inlined in float precision yet. In double precision, this has high variance, with an average gain of 2% for amd64 and 0.7% for i386 (but a much larger gain for usual cases) and some losses.
show more ...
|
#
70d818a2 |
| 25-Feb-2008 |
Bruce Evans <bde@FreeBSD.org> |
Change __ieee754_rem_pio2f() to return double instead of float so that this function and its callers cosf(), sinf() and tanf() don't waste time converting values from doubles to floats and back for |
Change __ieee754_rem_pio2f() to return double instead of float so that this function and its callers cosf(), sinf() and tanf() don't waste time converting values from doubles to floats and back for |x| > 9pi/4. All these functions were optimized a few years ago to mostly use doubles internally and across the __kernel*() interfaces but not across the __ieee754_rem_pio2f() interface.
This saves about 40 cycles in cosf(), sinf() and tanf() for |x| > 9pi/4 on amd64 (A64), and about 20 cycles on i386 (A64) (except for cosf() and sinf() in the upper range). 40 cycles is about 35% for |x| < 9pi/4 <= 2**19pi/2 and about 5% for |x| > 2**19pi/2. The saving is much larger on amd64 than on i386 since the conversions are not easy to optimize except on i386 where some of them are automatic and others are optimized invalidly. amd64 is still about 10% slower in cosf() and tanf() in the lower range due to conversion overhead.
This also gives a tiny speedup for |x| <= 9pi/4 on amd64 (by simplifying the code). It also avoids compiler bugs and/or additional slowness in the conversions on (not yet supported) machines where double_t != double.
show more ...
|
#
0d1564b6 |
| 25-Feb-2008 |
Bruce Evans <bde@FreeBSD.org> |
Fix some off-by-1 errors.
e_rem_pio2.c: Float and double precision didn't work because init_jk[] was 1 too small. It needs to be 2 larger than you might expect, and 1 larger than it was for these pr
Fix some off-by-1 errors.
e_rem_pio2.c: Float and double precision didn't work because init_jk[] was 1 too small. It needs to be 2 larger than you might expect, and 1 larger than it was for these precisions, since its test for recomputing needs a margin of 47 bits (almost 2 24-bit units).
init_jk[] seems to be barely enough for extended and quad precisions. This hasn't been completely verified. Callers now get about 24 bits of extra precision for float, and about 19 for double, but only about 8 for extended and quad. 8 is not enough for callers that want to produce extra-precision results, but current callers have rounding errors of at least 0.8 ulps, so another 1/2**8 ulps of error from the reduction won't affect them much.
Add a comment about some of the magic for init_jk[].
e_rem_pio2.c: Double precision worked in practice because of a compensating off-by-1 error here. Extended precision was asked for, and it executed exactly the same code as the unbroken double precision.
e_rem_pio2f.c: Float precision worked in practice because of a compensating off-by-1 error here. Double precision was asked for, and was almost needed, since the cosf() and sinf() callers want to produce extra-precision results, at least internally so that their error is only 0.5009 ulps. However, the extra precision provided by unbroken float precision is enough, and the double-precision code has extra overheads, so the off-by-1 error cost about 5% in efficiency on amd64 and i386.
show more ...
|
Revision tags: release/7.0.0_cvs, release/7.0.0 |
|
#
60a50c25 |
| 23-Feb-2008 |
Bruce Evans <bde@FreeBSD.org> |
Optimize the 9pi/2 < |x| <= 2**19pi/2 case some more by avoiding an fabs(), a conditional branch, and sign adjustments of 3 variables for x < 0 when the branch is taken. In double precision, even wh
Optimize the 9pi/2 < |x| <= 2**19pi/2 case some more by avoiding an fabs(), a conditional branch, and sign adjustments of 3 variables for x < 0 when the branch is taken. In double precision, even when the branch is perfectly predicted, this saves about 10 cycles or 10% on amd64 (A64) and i386 (A64) for the negative half of the range, but makes little difference for the positive half of the range. In float precision, it also saves about 4 cycles for the positive half of the range on i386, and many more cycles in both halves on amd64 (28 in the negative half and 11 in the positive half for tanf), but the amd64 times for float precision are anomalously slow so the larger improvement is only a side effect.
Previous commits arranged for the x < 0 case to be handled simply: - one part of the rounding method uses the magic number 0x1.8p52 instead of the usual 0x1.0p52. The latter is required for large |x|, but it doesn't work for negative x and we don't need it for large |x|. - another part of the rounding method no longer needs to add `half'. It would have needed to add -half for negative x. - removing the "quick check no cancellation" in the double precision case removed the need to take the absolute value of the quadrant number.
Add my noncopyright in e_rem_pio2.c
show more ...
|