summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--math/libm-test.inc2
-rw-r--r--sysdeps/i386/fpu/s_frexpl.S9
-rw-r--r--sysdeps/ieee754/dbl-64/s_frexp.c2
-rw-r--r--sysdeps/ieee754/dbl-64/wordsize-64/s_frexp.c3
-rw-r--r--sysdeps/ieee754/flt-32/s_frexpf.c2
-rw-r--r--sysdeps/ieee754/ldbl-128/s_frexpl.c2
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_frexpl.c2
-rw-r--r--sysdeps/ieee754/ldbl-96/s_frexpl.c2
9 files changed, 33 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 84e6720fa4..49fc9e7800 100644
--- a/ChangeLog
+++ b/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.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 3d901ae96a..81ca896626 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -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),
diff --git a/sysdeps/i386/fpu/s_frexpl.S b/sysdeps/i386/fpu/s_frexpl.S
index f687ab3c2e..b33a8a8573 100644
--- a/sysdeps/i386/fpu/s_frexpl.S
+++ b/sysdeps/i386/fpu/s_frexpl.S
@@ -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)
diff --git a/sysdeps/ieee754/dbl-64/s_frexp.c b/sysdeps/ieee754/dbl-64/s_frexp.c
index 1b8d8500ba..874214ec7c 100644
--- a/sysdeps/ieee754/dbl-64/s_frexp.c
+++ b/sysdeps/ieee754/dbl-64/s_frexp.c
@@ -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;
diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_frexp.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_frexp.c
index 42068f8187..4b075b7200 100644
--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_frexp.c
+++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_frexp.c
@@ -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;
diff --git a/sysdeps/ieee754/flt-32/s_frexpf.c b/sysdeps/ieee754/flt-32/s_frexpf.c
index 67a28d3603..005367cf58 100644
--- a/sysdeps/ieee754/flt-32/s_frexpf.c
+++ b/sysdeps/ieee754/flt-32/s_frexpf.c
@@ -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);
diff --git a/sysdeps/ieee754/ldbl-128/s_frexpl.c b/sysdeps/ieee754/ldbl-128/s_frexpl.c
index d61dddaaaa..70b2d3ae19 100644
--- a/sysdeps/ieee754/ldbl-128/s_frexpl.c
+++ b/sysdeps/ieee754/ldbl-128/s_frexpl.c
@@ -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);
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c b/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
index 52d2d3ea90..210c5d2ed4 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
@@ -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)
diff --git a/sysdeps/ieee754/ldbl-96/s_frexpl.c b/sysdeps/ieee754/ldbl-96/s_frexpl.c
index ab217a659b..799880f373 100644
--- a/sysdeps/ieee754/ldbl-96/s_frexpl.c
+++ b/sysdeps/ieee754/ldbl-96/s_frexpl.c
@@ -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);