diff options
author | Joseph Myers <joseph@codesourcery.com> | 2016-06-23 22:17:41 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2016-06-23 22:17:41 +0000 |
commit | 40244be3729149ff440caf18e445ec17b0d0b511 (patch) | |
tree | 17752b5c0173889687263d735f6f259909e31c5a /math | |
parent | 7ed84b89f344c54dbf8665cb1cd29044bec62d18 (diff) | |
download | glibc-40244be3729149ff440caf18e445ec17b0d0b511.tar glibc-40244be3729149ff440caf18e445ec17b0d0b511.tar.gz glibc-40244be3729149ff440caf18e445ec17b0d0b511.tar.bz2 glibc-40244be3729149ff440caf18e445ec17b0d0b511.zip |
Fix i386/x86_64 scalbl with sNaN input (bug 20296).
The x86_64 and i386 versions of scalbl return sNaN for some cases of
sNaN input and are missing "invalid" exceptions for other cases. This
results from overly complicated code that either returns a NaN input,
or discards both inputs when one is NaN and loads a NaN from memory.
This patch fixes this by simplifying the code to add the arguments
when either one is NaN.
Tested for x86_64 and x86.
[BZ #20296]
* sysdeps/i386/fpu/e_scalbl.S (__ieee754_scalbl): Add arguments
when either argument is a NaN.
* sysdeps/x86_64/fpu/e_scalbl.S (__ieee754_scalbl): Likewise.
* math/libm-test.inc (scalb_test_data): Add sNaN tests.
Diffstat (limited to 'math')
-rw-r--r-- | math/libm-test.inc | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/math/libm-test.inc b/math/libm-test.inc index 3e4ef187c3..7334a48577 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -11598,6 +11598,10 @@ static const struct test_ff_f_data scalb_test_data[] = TEST_ff_f (scalb, 0, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, 1, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, 1, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, 0, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, 0, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, 1, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, 1, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, 1, 0, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, -1, 0, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), @@ -11634,28 +11638,60 @@ static const struct test_ff_f_data scalb_test_data[] = TEST_ff_f (scalb, qnan_value, 1, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, -qnan_value, 1, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, snan_value, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -snan_value, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, 1, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, 1, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, 1, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, 1, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, qnan_value, 0.5, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, -qnan_value, 0.5, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, snan_value, 0.5, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -snan_value, 0.5, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, 0.5, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, 0.5, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, 0.5, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, 0.5, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, -qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, snan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -snan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, 0, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, 0, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, 0, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, -qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, snan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -snan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, plus_infty, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, plus_infty, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, plus_infty, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, -qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, snan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -snan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, minus_infty, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, minus_infty, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, minus_infty, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, -qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_ff_f (scalb, -qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (scalb, snan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, snan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -snan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -snan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, qnan_value, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, qnan_value, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -qnan_value, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -qnan_value, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, snan_value, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, snan_value, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -snan_value, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_ff_f (scalb, -snan_value, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_ff_f (scalb, max_value, max_value, plus_oflow, INEXACT_EXCEPTION|OVERFLOW_EXCEPTION|ERRNO_PLUS_OFLOW), TEST_ff_f (scalb, max_value, -max_value, plus_uflow, INEXACT_EXCEPTION|UNDERFLOW_EXCEPTION|ERRNO_PLUS_UFLOW), |