mirror of git://sourceware.org/git/glibc.git
Fix frexp (NaN) (bug 20250).
Various implementations of frexp functions return sNaN for sNaN input. This patch fixes them to add such arguments to themselves so that qNaN is returned. Tested for x86_64, x86, mips64 and powerpc. [BZ #20250] * sysdeps/i386/fpu/s_frexpl.S (__frexpl): Add non-finite input to itself. * sysdeps/ieee754/dbl-64/s_frexp.c (__frexp): Add non-finite or zero input to itself. * sysdeps/ieee754/dbl-64/wordsize-64/s_frexp.c (__frexp): Likewise. * sysdeps/ieee754/flt-32/s_frexpf.c (__frexpf): Likewise. * sysdeps/ieee754/ldbl-128/s_frexpl.c (__frexpl): Likewise. * sysdeps/ieee754/ldbl-128ibm/s_frexpl.c (__frexpl): Likewise. * sysdeps/ieee754/ldbl-96/s_frexpl.c (__frexpl): Likewise. * math/libm-test.inc (frexp_test_data): Add sNaN tests.
This commit is contained in:
parent
b39b6e0c90
commit
88283451b2
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2016-06-13 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
[BZ #20250]
|
||||
* sysdeps/i386/fpu/s_frexpl.S (__frexpl): Add non-finite input to
|
||||
itself.
|
||||
* sysdeps/ieee754/dbl-64/s_frexp.c (__frexp): Add non-finite or
|
||||
zero input to itself.
|
||||
* sysdeps/ieee754/dbl-64/wordsize-64/s_frexp.c (__frexp):
|
||||
Likewise.
|
||||
* sysdeps/ieee754/flt-32/s_frexpf.c (__frexpf): Likewise.
|
||||
* sysdeps/ieee754/ldbl-128/s_frexpl.c (__frexpl): Likewise.
|
||||
* sysdeps/ieee754/ldbl-128ibm/s_frexpl.c (__frexpl): Likewise.
|
||||
* sysdeps/ieee754/ldbl-96/s_frexpl.c (__frexpl): Likewise.
|
||||
* math/libm-test.inc (frexp_test_data): Add sNaN tests.
|
||||
|
||||
2016-06-13 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
* nptl/Makefile (test): Add tst-cancel4_1 and tst-cancel4_2.
|
||||
|
|
|
@ -7760,6 +7760,8 @@ static const struct test_f_f1_data frexp_test_data[] =
|
|||
TEST_fI_f1 (frexp, minus_infty, minus_infty, IGNORE, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_fI_f1 (frexp, qnan_value, qnan_value, IGNORE, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_fI_f1 (frexp, -qnan_value, qnan_value, IGNORE, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_fI_f1 (frexp, snan_value, qnan_value, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_fI_f1 (frexp, -snan_value, qnan_value, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
|
||||
TEST_fI_f1 (frexp, 0.0, 0.0, 0.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_fI_f1 (frexp, minus_zero, minus_zero, 0.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
|
|
|
@ -50,7 +50,7 @@ ENTRY (__frexpl)
|
|||
jz 1f
|
||||
xorl %ecx, %ecx
|
||||
cmpl $0x7fff, %eax
|
||||
je 1f
|
||||
je 3f
|
||||
|
||||
cmpl $0, %eax
|
||||
jne 2f
|
||||
|
@ -81,5 +81,12 @@ ENTRY (__frexpl)
|
|||
movl %ecx, (%eax)
|
||||
|
||||
ret
|
||||
|
||||
/* Infinity or NaN; ensure signaling NaNs are quieted. */
|
||||
3: movl EXPP(%esp), %eax
|
||||
fldt VAL0(%esp)
|
||||
fadd %st
|
||||
movl %ecx, (%eax)
|
||||
ret
|
||||
END (__frexpl)
|
||||
weak_alias (__frexpl, frexpl)
|
||||
|
|
|
@ -38,7 +38,7 @@ __frexp (double x, int *eptr)
|
|||
ix = 0x7fffffff & hx;
|
||||
*eptr = 0;
|
||||
if (ix >= 0x7ff00000 || ((ix | lx) == 0))
|
||||
return x; /* 0,inf,nan */
|
||||
return x + x; /* 0,inf,nan */
|
||||
if (ix < 0x00100000) /* subnormal */
|
||||
{
|
||||
x *= two54;
|
||||
|
|
|
@ -55,6 +55,9 @@ __frexp (double x, int *eptr)
|
|||
ix = (ix & INT64_C (0x800fffffffffffff)) | INT64_C (0x3fe0000000000000);
|
||||
INSERT_WORDS64 (x, ix);
|
||||
}
|
||||
else
|
||||
/* Quiet signaling NaNs. */
|
||||
x += x;
|
||||
|
||||
*eptr = e;
|
||||
return x;
|
||||
|
|
|
@ -29,7 +29,7 @@ float __frexpf(float x, int *eptr)
|
|||
GET_FLOAT_WORD(hx,x);
|
||||
ix = 0x7fffffff&hx;
|
||||
*eptr = 0;
|
||||
if(ix>=0x7f800000||(ix==0)) return x; /* 0,inf,nan */
|
||||
if(ix>=0x7f800000||(ix==0)) return x + x; /* 0,inf,nan */
|
||||
if (ix<0x00800000) { /* subnormal */
|
||||
x *= two25;
|
||||
GET_FLOAT_WORD(hx,x);
|
||||
|
|
|
@ -39,7 +39,7 @@ long double __frexpl(long double x, int *eptr)
|
|||
GET_LDOUBLE_WORDS64(hx,lx,x);
|
||||
ix = 0x7fffffffffffffffULL&hx;
|
||||
*eptr = 0;
|
||||
if(ix>=0x7fff000000000000ULL||((ix|lx)==0)) return x; /* 0,inf,nan */
|
||||
if(ix>=0x7fff000000000000ULL||((ix|lx)==0)) return x + x;/* 0,inf,nan */
|
||||
if (ix<0x0001000000000000ULL) { /* subnormal */
|
||||
x *= two114;
|
||||
GET_LDOUBLE_MSW64(hx,x);
|
||||
|
|
|
@ -47,7 +47,7 @@ long double __frexpl(long double x, int *eptr)
|
|||
{
|
||||
/* 0,inf,nan. */
|
||||
*eptr = expon;
|
||||
return x;
|
||||
return x + x;
|
||||
}
|
||||
expon = ix >> 52;
|
||||
if (expon == 0)
|
||||
|
|
|
@ -46,7 +46,7 @@ long double __frexpl(long double x, int *eptr)
|
|||
GET_LDOUBLE_WORDS(se,hx,lx,x);
|
||||
ix = 0x7fff&se;
|
||||
*eptr = 0;
|
||||
if(ix==0x7fff||((ix|hx|lx)==0)) return x; /* 0,inf,nan */
|
||||
if(ix==0x7fff||((ix|hx|lx)==0)) return x + x; /* 0,inf,nan */
|
||||
if (ix==0x0000) { /* subnormal */
|
||||
x *= two65;
|
||||
GET_LDOUBLE_EXP(se,x);
|
||||
|
|
Loading…
Reference in New Issue