C/C++) in exp(3), expf(3), expm1(3) and expm1f(3) during intermediate
computations that compute the IEEE-754 bit pattern for |2**k| for
integer |k|.
The implementations of exp(3), expf(3), expm1(3) and expm1f(3) need to
compute IEEE-754 bit patterns for 2**k in certain places. (k is an
integer and 2**k is exactly representable in IEEE-754.)
Currently they do things like 0x3FF0'0000+(k<<20), which is to say they
take the bit pattern representing 1 and then add directly to the
exponent field to get the desired power of two. This is fine when k is
non-negative.
But when k<0 (and certain classes of input trigger this), this
left-shifts a negative number -- an operation with undefined behavior in
C and C++.
The desired semantics can be achieved by instead adding the
possibly-negative k to the IEEE-754 exponent bias to get the desired
exponent field, _then_ shifting that into its proper overall position.
(Note that in case of s_expm1.c and s_expm1f.c, there are SET_HIGH_WORD
and SET_FLOAT_WORD uses further down in each of these files that perform
shift operations involving k, but by these points k's range has been
restricted to 2 < k <= 56, and the shift operations under those
circumstances can't do anything that would be UB.)
Submitted by: Jeff Walden, https://github.com/jswalden
Obtained from: https://github.com/freebsd/freebsd/pull/411
Obtained from: https://github.com/freebsd/freebsd/pull/412
MFC after: 3 days
This unskips:
- lib.libc.stdlib.strtod_test.strtod_round
- lib.msun.fe_round_test.t_nofe_round
In lib/msun/tests/Makefile only define on fe_round_test.c because
lib.msun.ilogb_test.ilogb will get wrong results and needs more examination.
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
This makes it possible to perform mathematical operations on
fractional values without using floating point. It operates on Q
numbers, which are integer-sized, opaque structures initialized
to hold a chosen number of integer and fractional bits.
For a general description of the Q number system, see the "Fixed Point
Representation & Fractional Math" whitepaper[1]; for the actual
API see the qmath(3) man page.
This is one of dependencies for the upcoming stats(3) framework[2]
that will be applied to the TCP stack in a later commit.
1. https://www.superkits.net/whitepapers/Fixed%20Point%20Representation%20&%20Fractional%20Math.pdf
2. https://reviews.freebsd.org/D20477
Reviewed by: bcr (man pages, earlier version), sef (earlier version)
Discussed with: cem, dteske, imp, lstewart
Sponsored By: Klara Inc, Netflix
Obtained from: Netflix
Differential Revision: https://reviews.freebsd.org/D20116
Ensure the expected result is stored first in a volatile variable with
the desired type. This makes all the tests succeed.
Slightly changed from the original pull request, but functionally the
same.
Obtained from: https://github.com/freebsd/freebsd/pull/401
Submitted by: Moritz Buhl <gh@moritzbuhl.de>
PR: 191676
MFC after: 3 days
Replace calls to sinf(x) and cosf(x) with a single call to sincosf().
Submitted by: Steve Kargl <sgk@troutmask.apl.washington.edu>
Reviewed by: bde
Approved by: grog
MFC after: 3 days
trig_test.reduction test cases to fail, if the fixes from r343916 have
not yet been applied to the base compiler.
Reported by: lwhsu
PR: 234040
Upstream PR: https://bugs.llvm.org/show_bug.cgi?id=40206
MFC after: 1 week
j is int32_t and thus j<<31 is undefined if j==1.
Hinted by: muusl-lib (git 688d3da0f1730daddbc954bbc2d27cc96ceee04c)
Discussed with: freebsd-numerics (kargl)
The long double aliases of double functions are only exposed as aliases if
LDBL_MANT_DIG is 53 (same as DBL_MANT_DIG). Without float.h included these
files were not exposing weak aliases as expected, leading to link failures
if programs use the *l functions. This should fix editors/calligra on
targets with 64-bit long double, which uses erfl and erfcl. Found on
powerpc64.
Reviewed by: kargl@
of NaNs before possible returning a NaN.
The remquo*() and remainder*() functions should now give bitwise identical
results across arches and implementations, and bitwise consistent results
(with lower precisions having truncated mantissas) across precisions. x86
already had consistency across amd64 and i386 and precisions by using the
i387 consistently and normally not using the C versions. Inconsistencies
for C reqmquol() were first detected on sparc64.
Remove double second clearing of the sign bit and extra blank lines.
remainder*(x, y) and remquo*(x, y, quo) were broken for y = 0 by changing
multiplication by y to addition of y. (When y is 0, the result should be
NaN but became 1 for finite x.)
Use a new macro nan_mix_op() to give more control over the mixing, and
expand comments.
Recent re-testing missed finding this bug since I only tested the macro
version on amd64 and i386 and these arches don't use the C versions (they
use either asm versions or builtins).
Reported by: enh via freebsd-numerics
This is a follow-up to r336299.
* lib/msun/Makefile:
. Remove polevll.c
* lib/msun/ld80/e_powl.c:
. Copy contents of polevll.c to here. This is the only consumer of
these functions. Make functions 'static inline'.
. Make reducl a 'static inline' function.
* lib/msun/man/exp.3:
. Remove BUGS section that no longer applies.
* lib/msun/src/math_private.h:
. Remove prototypes of __p1evll() and __polevll()
* lib/msun/src/s_cpow.c:
* lib/msun/src/s_cpowf.c:
* lib/msun/src/s_cpowl.c
. Include math_private.h.
. Use the CMPLX macro from either C99 or math_private.h (depends on
compiler support) instead of the problematic use of complex I.
Submitted by: Steve Kargl <sgk@troutmask.apl.washington.edu>
PR: 229876
MFC after: 1 week
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.
cc1: warnings being treated as errors
/usr/src/lib/msun/src/s_cpow.c: In function 'cpow':
/usr/src/lib/msun/src/s_cpow.c:63: warning: implicit declaration of function 'CMPLX'
This is a follow-up to r336299.
* lib/msun/Makefile:
. Remove polevll.c
* lib/msun/ld80/e_powl.c:
. Copy contents of polevll.c to here. This is the only consumer of
these functions. Make functions 'static inline'.
. Make reducl a 'static inline' function.
* lib/msun/man/exp.3:
. Remove BUGS section that no longer applies.
* lib/msun/src/math_private.h:
. Remove prototypes of __p1evll() and __polevll()
* lib/msun/src/s_cpow.c:
* lib/msun/src/s_cpowf.c:
* lib/msun/src/s_cpowl.c
. Use the CMPLX macro from either C99 or math_private.h (depends of
compiler support) instead of the problematic use of complex I.
Submitted by: Steve Kargl <sgk@troutmask.apl.washington.edu>
PR: 229876
MFC after: 1 week
with 1 huge component and 1 tiny (but nowhere near denormal) component.
Rescale earlier so that a scale factor of 2 can be combined with a non-
scale divisor of 2, so that the division doesn't shift out a bit. In the
usual case where the scale factor is just 1, the division may shift out a
bit, but then the underflow is not spurious and the inaccuracies are harder
to fix.
Remove the STDC CX_LIMITED_RANGE pragma and its verbose comment. We still
don't have any C99 compilers (that support fenv pragmas), and if we did
then there are thousands of other places in libm that would need to use
them more than here.
The other cleanups are smaller.
and csqrtl().
When one component is huge and the other is tiny, scaling down the tiny
component gave spurious underflow.
When both components are denormal, not scaling them up gave inaccuracies
of 34+ ulps on not very carefully selected args. Fixing this reduces the
maximum error to 1.6 ulps on the same set of args (mosly not denormal ones).
The scaling used multiplication of a complex variable by 2, but clang messes
this on amd64 up by losing the sign of -0.0. Calculate the components
separately, as is well known to be needed for operations on more exceptional
values.
independent of the precision in most cases. This is mainly to simplify
checking for errors. r176266 did this for e_pow[f].c using a less
refined expression that often didn't work. r176276 fixes an error in
the log message for r176266. The main refinement is to always expand
to long double precision. See old log messages (especially these 2)
and the comment on the macro for more general details.
Specific details:
- using nan_mix() consistently for the new and old pow*() functions was
the only thing needed to make my consistency test for powl() vs pow()
pass on amd64.
- catrig[fl].c already had all the refinements, but open-coded.
- e_atan2[fl].c, e_fmod[fl].c and s_remquo[fl] only had primitive NaN
mixing.
- e_hypot[fl].c already had a different refined version of r176266. Refine
this further. nan_mix() is not directly usable here since we want to
clear the sign bit.
- e_remainder[f].c already had an earlier version of r176266.
- s_ccosh[f].c,/s_csinh[f].c already had a version equivalent to r176266.
Refine this further. nan_mix() is not directly usable here since the
expression has to handle some non-NaN cases.
- s_csqrt.[fl]: the mixing was special and mostly wrong. Partially fix the
special version.
- s_ctanh[f].c already had a version of r176266.
This corresponds to the latest status (hasn't changed in 9+
years) from openbsd of ld80/ld128 powl, and source cpowf, cpow,
cpowl (the complex power functions for float complex, double
complex, and long double complex) which are required for C99
compliance and were missing from FreeBSD. Also required for
some numerical codes using complex numbered Hamiltonians.
Thanks to jhb for tracking down the issue with making
weak_reference compile on powerpc.
When asked to review, bde said "I don't like it" - but
provided no actionable feedback or superior implementations.
Discussed with: jhb
Submitted by: jmd
Differential Revision: https://reviews.freebsd.org/D15919
Remove unnecessary casts, use integer literal constants instead of
floating point constants where possible, and introduce three const
static variables to hold 0.5, 0.25, and 1/3.
PR: 229420
Submitted by: Steve Kargl <sgk@troutmask.apl.washington.edu>
MFC after: 1 week
This is a follow-up to r321483, which disabled -Wmacro-redefined for
some lib/msun tests.
If an application included both fenv.h and ieeefp.h, several macros such
as __fldcw(), __fldenv() were defined in both headers, with slightly
different arguments, leading to conflicts.
Fix this by putting all the common macros in the machine-specific
versions of ieeefp.h. Where needed, update the arguments in places
where the macros are invoked.
This also slightly reduces the differences between the amd64 and i386
versions of ieeefp.h.
Reviewed by: kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D15633
With SOFTFLOAT, libc and libm were built correctly, but any program
including fenv.h itself assumed it was on a hardfloat systen and emitted
inline fpu instructions for fedisableexcept() and friends.
Unlike r315424 which did this for MIPS, I've used riscv_float_abi_soft
and riscv_float_abi_double macros as appropriate rather than using
__riscv_float_abi_soft exclusively. This ensures that attempts to use an
unsupported hardfloat ABI will fail.
Reviewed by: br
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D10039
As a component of atan2(y, x), the case of x == 1.0 is farmed out to
atan(y). The current implementation of this comparison is vulnerable
to signed integer underflow (that is, undefined behavior), and it's
performed in a somewhat more complicated way than it need be. Change
it to not be quite so cute, rather directly comparing the high/low
bits of x to the specific IEEE-754 bit pattern that encodes 1.0.
Note that while there are three different e_atan* files in the
relevant directory, only this one needs fixing. e_atan2f.c already
compares against the full bit pattern encoding 1.0f, while
e_atan2l.cuses bitwise-ands/ors/nots and so doesn't require a change.
Closes#130
Submitted by: Jeff Walden (@jswalden github PR #130)
Reviewed by: bde
MFC After: 1 month
Mainly focus on files that use BSD 2-Clause license, however the tool I
was using mis-identified many licenses so this was mostly a manual - error
prone - task.
The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.
The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.
Special thanks to Wind River for providing access to "The Duke of
Highlander" tool: an older (2014) run over FreeBSD tree was useful as a
starting point.
Initially, only tag files that use BSD 4-Clause "Original" license.
RelNotes: yes
Differential Revision: https://reviews.freebsd.org/D13133
Make armv7 as a new MACHINE_ARCH.
Copy all the places we do armv6 and add armv7 as basically an
alias. clang appears to generate code for armv7 by default. armv7 hard
float isn't supported by the the in-tree gcc, so it hasn't been
updated to have a new default.
Support armv7 as a new valid MACHINE_ARCH (and by extension
TARGET_ARCH).
Add armv7 to the universe build.
Differential Revision: https://reviews.freebsd.org/D12010
LDBL_MAX is broken on i386:
https://lists.freebsd.org/pipermail/freebsd-numerics/2012-September/000288.html
Gcc has produced +Infinity for LDBL_MAX on i386 and amd64 with -m32
for some time, and newer versions of gcc are now warning that the
"floating constant exceeds range of 'long double'". Avoid this by
referring to proxy values instead.
Reviewed by: bde
Approved by: markj (mentor)
Sponsored by: Dell EMC Isilon
directories to SUBDIR.${MK_TESTS} idiom
This is being done to pave the way for future work (and homogenity) in
^/projects/make-check-sandbox .
No functional change intended.
MFC after: 1 weeks
The empty (unimplemented) test inputs for sparc64 trigger a -Wtype-limits build
failure because nitems of an empty array is always false, i.e., deadcode.
MFC after: 1 month
MFC with: r321455
Reported by: Jenkins (sparc64 job)