/freebsd/lib/msun/src/ |
H A D | s_expm1.c | diff 5763a8cf06a297c067aa7af13973f50ab44c2a4d Wed Sep 25 20:50:57 CEST 2019 Dimitry Andric <dim@FreeBSD.org> Do not left-shift a negative number (inducing undefined behavior in 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
|
H A D | s_expm1f.c | diff 5763a8cf06a297c067aa7af13973f50ab44c2a4d Wed Sep 25 20:50:57 CEST 2019 Dimitry Andric <dim@FreeBSD.org> Do not left-shift a negative number (inducing undefined behavior in 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
|
H A D | e_exp.c | diff 5763a8cf06a297c067aa7af13973f50ab44c2a4d Wed Sep 25 20:50:57 CEST 2019 Dimitry Andric <dim@FreeBSD.org> Do not left-shift a negative number (inducing undefined behavior in 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
|
H A D | e_expf.c | diff 5763a8cf06a297c067aa7af13973f50ab44c2a4d Wed Sep 25 20:50:57 CEST 2019 Dimitry Andric <dim@FreeBSD.org> Do not left-shift a negative number (inducing undefined behavior in 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
|