about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2014-06-18 12:32:01 +0000
committerJoseph Myers <joseph@codesourcery.com>2014-06-18 12:32:01 +0000
commit4ba7a00fe3779e6ffafad6d47305b3491cdac33e (patch)
tree8735df5c818ab5022e97f53c3fd69be723299a45
parentb3a9f56ba59c3d8eadd3135a1c25c37a63151450 (diff)
downloadglibc-4ba7a00fe3779e6ffafad6d47305b3491cdac33e.tar.gz
glibc-4ba7a00fe3779e6ffafad6d47305b3491cdac33e.tar.xz
glibc-4ba7a00fe3779e6ffafad6d47305b3491cdac33e.zip
Fix __ieee754_logl (-LDBL_MAX) in FE_DOWNWARD mode (bug 17022).
This patch fixes __ieee754_logl (-LDBL_MAX) on x86_64 and x86 not to
subtract 1 from its argument and so cause spurious overflow in
FE_DOWNWARD mode.  (For any argument strictly less than -1, it doesn't
matter whether or not 1 is subtracted before computing log1p, as long
as the result doesn't overflow to -Inf.)

Tested x86_64 and x86.  (This particular case lacks test coverage,
since the testsuite doesn't cover -lieee, but it will be covered by
tests after the following patch to test pow in all rounding modes,
which was the context in which this bug was found.)

	[BZ #17022]
	* sysdeps/i386/fpu/e_logl.S (__ieee754_logl): Do not subtract 1
	from arguments -2 or below.
	* sysdeps/i386/i686/fpu/e_logl.S (__ieee754_logl): Likewise.
	* sysdeps/x86_64/fpu/e_logl.S (__ieee754_logl): Likewise.
-rw-r--r--ChangeLog8
-rw-r--r--NEWS4
-rw-r--r--sysdeps/i386/fpu/e_logl.S5
-rw-r--r--sysdeps/i386/i686/fpu/e_logl.S5
-rw-r--r--sysdeps/x86_64/fpu/e_logl.S5
5 files changed, 22 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 997cec628a..3204c4e046 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-06-18  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #17022]
+	* sysdeps/i386/fpu/e_logl.S (__ieee754_logl): Do not subtract 1
+	from arguments -2 or below.
+	* sysdeps/i386/i686/fpu/e_logl.S (__ieee754_logl): Likewise.
+	* sysdeps/x86_64/fpu/e_logl.S (__ieee754_logl): Likewise.
+
 2014-06-18  Andreas Schwab  <schwab@suse.de>
 
 	[BZ #17062]
diff --git a/NEWS b/NEWS
index 429dba5f2e..0c4d8bb184 100644
--- a/NEWS
+++ b/NEWS
@@ -19,8 +19,8 @@ Version 2.20
   16791, 16796, 16799, 16800, 16815, 16823, 16824, 16831, 16838, 16849,
   16854, 16876, 16877, 16878, 16882, 16885, 16888, 16890, 16912, 16915,
   16916, 16917, 16922, 16927, 16928, 16932, 16943, 16958, 16965, 16966,
-  16967, 16977, 16978, 16984, 16990, 16996, 17009, 17031, 17042, 17048,
-  17058, 17062.
+  16967, 16977, 16978, 16984, 16990, 16996, 17009, 17022, 17031, 17042,
+  17048, 17058, 17062.
 
 * The minimum Linux kernel version that this version of the GNU C Library
   can be used with is 2.6.32.
diff --git a/sysdeps/i386/fpu/e_logl.S b/sysdeps/i386/fpu/e_logl.S
index edae1d70df..828e98aa8d 100644
--- a/sysdeps/i386/fpu/e_logl.S
+++ b/sysdeps/i386/fpu/e_logl.S
@@ -40,8 +40,11 @@ ENTRY(__ieee754_logl)
 	fld	%st		// x : x : log(2)
 	sahf
 	jc	3f		// in case x is NaN or +-Inf
+	movzwl	4+8(%esp), %eax
+	cmpl	$0xc000, %eax
+	jae	6f		// x <= -2, avoid overflow from -LDBL_MAX - 1.
 4:	fsubl	MO(one)		// x-1 : x : log(2)
-	fld	%st		// x-1 : x-1 : x : log(2)
+6:	fld	%st		// x-1 : x-1 : x : log(2)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fcompl	MO(limit)	// x-1 : x : log(2)
 	fnstsw			// x-1 : x : log(2)
diff --git a/sysdeps/i386/i686/fpu/e_logl.S b/sysdeps/i386/i686/fpu/e_logl.S
index a0d1107dc0..0ccc8fc71e 100644
--- a/sysdeps/i386/i686/fpu/e_logl.S
+++ b/sysdeps/i386/i686/fpu/e_logl.S
@@ -39,8 +39,11 @@ ENTRY(__ieee754_logl)
 	LOAD_PIC_REG (dx)
 #endif
 	fld	%st		// x : x : log(2)
+	movzwl	4+8(%esp), %eax
+	cmpl	$0xc000, %eax
+	jae	5f		// x <= -2, avoid overflow from -LDBL_MAX - 1.
 	fsubl	MO(one)		// x-1 : x : log(2)
-	fld	%st		// x-1 : x-1 : x : log(2)
+5:	fld	%st		// x-1 : x-1 : x : log(2)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fld	MO(limit)	// 0.29 : |x-1| : x-1 : x : log(2)
 	fcomip	%st(1)		// |x-1| : x-1 : x : log(2)
diff --git a/sysdeps/x86_64/fpu/e_logl.S b/sysdeps/x86_64/fpu/e_logl.S
index 315afc0033..047b8db88a 100644
--- a/sysdeps/x86_64/fpu/e_logl.S
+++ b/sysdeps/x86_64/fpu/e_logl.S
@@ -38,8 +38,11 @@ ENTRY(__ieee754_logl)
 	fld	%st		// x : x : log(2)
 	testb	$1, %ah
 	jnz	3f		// in case x is NaN or +-Inf
+	movzwl	8+8(%rsp), %eax
+	cmpl	$0xc000, %eax
+	jae	6f		// x <= -2, avoid overflow from -LDBL_MAX - 1.
 4:	fsubl	MO(one)		// x-1 : x : log(2)
-	fld	%st		// x-1 : x-1 : x : log(2)
+6:	fld	%st		// x-1 : x-1 : x : log(2)
 	fabs			// |x-1| : x-1 : x : log(2)
 	fcompl	MO(limit)	// x-1 : x : log(2)
 	fnstsw			// x-1 : x : log(2)