GNU C Library master sources branch master updated. glibc-2.22-526-g71d1b01

jsm28@sourceware.org jsm28@sourceware.org
Wed Nov 11 00:06:00 GMT 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  71d1b0166b4ace0d804af2993b3815758b852efc (commit)
      from  fe534fe8980fa214c410e3661a4216e781073353 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=71d1b0166b4ace0d804af2993b3815758b852efc

commit 71d1b0166b4ace0d804af2993b3815758b852efc
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Wed Nov 11 00:06:09 2015 +0000

    Fix powerpc nearbyint wrongly clearing "inexact" and leaving traps disabled (bug 19228).
    
    Similar to bug 15491 recently fixed for x86_64 / x86, the powerpc
    (both powerpc32 and powerpc64) hard-float implementations of
    nearbyintf and nearbyint wrongly clear an "inexact" exception that was
    raised before the function was called; this shows up as failure of the
    test math/test-nearbyint-except added when that bug was fixed.  They
    also wrongly leave traps on "inexact" disabled if they were enabled
    before the function was called.
    
    This patch fixes the bugs similar to how the x86 bug was fixed: saving
    and restoring the whole floating-point state, both to restore the
    original "inexact" flag state and to restore the original state of
    whether traps on "inexact" were enabled.  Because there's a convenient
    point in the powerpc implementations to save state after any sNaN
    arguments will have raised "invalid" but before "inexact" traps need
    to be disabled, no special handling for "invalid" is needed as in the
    x86 version.
    
    Tested for powerpc64 and powerpc32, where it fixes the
    math/test-nearbyint-except failure as well as fixing the new test
    math/test-nearbyint-except-2 added by this patch.  Also tested for
    x86_64 and x86 that the new test passes.
    
    If powerpc experts see a more efficient way of doing this
    (e.g. instruction positioning that's better for pipelines on typical
    processors) then of course followups optimizing the fix are welcome.
    
    	[BZ #19228]
    	* sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S (__nearbyint): Save
    	and restore full floating-point state.
    	* sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S (__nearbyintf):
    	Likewise.
    	* sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S (__nearbyint):
    	Likewise.
    	* sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S (__nearbyintf):
    	Likewise.
    	* math/test-nearbyint-except-2.c: New file.
    	* math/Makefile (tests): Add test-nearbyint-except-2.

diff --git a/ChangeLog b/ChangeLog
index 51faaed..b23297b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2015-11-10  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #19228]
+	* sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S (__nearbyint): Save
+	and restore full floating-point state.
+	* sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S (__nearbyintf):
+	Likewise.
+	* sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S (__nearbyint):
+	Likewise.
+	* sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S (__nearbyintf):
+	Likewise.
+	* math/test-nearbyint-except-2.c: New file.
+	* math/Makefile (tests): Add test-nearbyint-except-2.
+
 2015-11-10  H.J. Lu  <hongjiu.lu@intel.com>
 
 	[BZ #19178]
diff --git a/math/Makefile b/math/Makefile
index ec9e6b2..06412f3 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -109,7 +109,8 @@ tests = test-matherr test-fenv atest-exp atest-sincos atest-exp2 basic-test \
 	test-tgmath-int test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 test-snan \
 	test-fenv-tls test-fenv-preserve test-fenv-return test-fenvinline \
 	test-nearbyint-except test-fenv-clear test-signgam-finite \
-	test-signgam-finite-c99 test-signgam-finite-c11 $(tests-static)
+	test-signgam-finite-c99 test-signgam-finite-c11 \
+	test-nearbyint-except-2 $(tests-static)
 tests-static = test-fpucw-static test-fpucw-ieee-static
 # We do the `long double' tests only if this data type is available and
 # distinct from `double'.
diff --git a/math/test-nearbyint-except-2.c b/math/test-nearbyint-except-2.c
new file mode 100644
index 0000000..04faac3
--- /dev/null
+++ b/math/test-nearbyint-except-2.c
@@ -0,0 +1,72 @@
+/* Test nearbyint functions do not disable exception traps (bug 19228).
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <fenv.h>
+#include <math.h>
+#include <stdio.h>
+
+#ifndef FE_INEXACT
+# define FE_INEXACT 0
+#endif
+
+#define TEST_FUNC(NAME, FLOAT, SUFFIX)					\
+static int								\
+NAME (void)								\
+{									\
+  int result = 0;							\
+  volatile FLOAT a, b __attribute__ ((unused));				\
+  a = 1.5;								\
+  /* nearbyint must work when traps on "inexact" are enabled.  */	\
+  b = nearbyint ## SUFFIX (a);						\
+  /* And it must have left those traps enabled.  */			\
+  if (fegetexcept () == FE_INEXACT)					\
+    puts ("PASS: " #FLOAT);						\
+  else									\
+    {									\
+      puts ("FAIL: " #FLOAT);						\
+      result = 1;							\
+    }									\
+  return result;							\
+}
+
+TEST_FUNC (float_test, float, f)
+TEST_FUNC (double_test, double, )
+#ifndef NO_LONG_DOUBLE
+TEST_FUNC (ldouble_test, long double, l)
+#endif
+
+static int
+do_test (void)
+{
+  if (feenableexcept (FE_INEXACT) == -1)
+    {
+      puts ("enabling FE_INEXACT traps failed, cannot test");
+      return 77;
+    }
+  int result = float_test ();
+  feenableexcept (FE_INEXACT);
+  result |= double_test ();
+#ifndef NO_LONG_DOUBLE
+  feenableexcept (FE_INEXACT);
+  result |= ldouble_test ();
+#endif
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S b/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S
index cee4c7b..27673b6 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S
@@ -52,19 +52,21 @@ ENTRY (__nearbyint)
 	bgelr	cr7
 	fcmpu	cr7,fp1,fp12	/* if (x > 0.0 */
 	ble	cr7,L(lessthanzero)
+	mffs	fp11
 	mtfsb0	4*cr7+lt	/* Disable FE_INEXACT exception */
 	fadd	fp1,fp1,fp13	/* x += TWO52 */
 	fsub	fp1,fp1,fp13	/* x -= TWO52 */
 	fabs	fp1,fp1		/* if (x == 0.0 */
-	mtfsb0	4*cr1+eq	/* Clear any FE_INEXACT exception */
+	mtfsf	0xff,fp11	/* Restore FE_INEXACT state.  */
 	blr
 L(lessthanzero):
 	bgelr	cr7
+	mffs	fp11
 	mtfsb0	4*cr7+lt	/* Disable FE_INEXACT exception */
 	fsub	fp1,fp1,fp13	/* x -= TWO52 */
 	fadd	fp1,fp1,fp13	/* x += TWO52 */
 	fnabs	fp1,fp1		/* if (x == 0.0) */
-	mtfsb0	4*cr1+eq	/* Clear any FE_INEXACT exception */
+	mtfsf	0xff,fp11	/* Restore FE_INEXACT state.  */
 	blr
 END (__nearbyint)
 
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S b/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S
index 96a39c6..a5084b2 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S
@@ -51,19 +51,21 @@ ENTRY (__nearbyintf)
 	bgelr	cr7
 	fcmpu	cr7,fp1,fp12		/* if (x > 0.0 */
 	ble	cr7,L(lessthanzero)
+	mffs	fp11
 	mtfsb0	4*cr7+lt		/* Disable FE_INEXACT exception */
 	fadds	fp1,fp1,fp13		/* x += TWO23 */
 	fsubs	fp1,fp1,fp13		/* x -= TWO23 */
 	fabs	fp1,fp1			/* if (x == 0.0) */
-	mtfsb0	4*cr1+eq		/* Clear any FE_INEXACT exception */
+	mtfsf	0xff,fp11		/* Restore FE_INEXACT state.  */
 	blr
 L(lessthanzero):
 	bgelr	cr7
+	mffs	fp11
 	mtfsb0	4*cr7+lt		/* Disable FE_INEXACT exception */
 	fsubs	fp1,fp1,fp13		/* x -= TWO23 */
 	fadds	fp1,fp1,fp13		/* x += TWO23 */
 	fnabs	fp1,fp1			/* if (x == 0.0) */
-	mtfsb0	4*cr1+eq		/* Clear any FE_INEXACT exception */
+	mtfsf	0xff,fp11		/* Restore FE_INEXACT state.  */
 	blr
 END (__nearbyintf)
 
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S b/sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S
index 6654840..9c87596 100644
--- a/sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S
+++ b/sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S
@@ -40,19 +40,21 @@ EALIGN (__nearbyint, 4, 0)
 	fsub	fp12,fp13,fp13	/* generate 0.0 */
 	fcmpu	cr7,fp1,fp12	/* if (x > 0.0) */
 	ble	cr7, L(lessthanzero)
+	mffs	fp11
 	mtfsb0	4*cr7+lt	/* Disable FE_INEXACT exception */
 	fadd	fp1,fp1,fp13	/* x+= TWO52 */
 	fsub	fp1,fp1,fp13	/* x-= TWO52 */
 	fabs	fp1,fp1		/* if (x == 0.0) */
-	mtfsb0	4*cr1+eq	/* Clear any FE_INEXACT exception */
+	mtfsf	0xff,fp11	/* Restore FE_INEXACT state.  */
 	blr			/* x = 0.0; */
 L(lessthanzero):
 	bgelr	cr7		/* if (x < 0.0) */
+	mffs	fp11
 	mtfsb0	4*cr7+lt
 	fsub	fp1,fp1,fp13	/* x -= TWO52 */
 	fadd	fp1,fp1,fp13	/* x += TWO52 */
 	fnabs	fp1,fp1		/* if (x == 0.0) */
-	mtfsb0	4*cr1+eq
+	mtfsf	0xff,fp11	/* Restore FE_INEXACT state.  */
 	blr			/* x = -0.0; */
 END (__nearbyint)
 
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S b/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S
index 041dfeb..9dfbce6 100644
--- a/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S
+++ b/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S
@@ -41,19 +41,21 @@ EALIGN (__nearbyintf, 4, 0)
 	fsubs	fp12,fp13,fp13	/* generate 0.0 */
 	fcmpu	cr7,fp1,fp12	/* if (x > 0.0)  */
 	ble	cr7, L(lessthanzero)
+	mffs	fp11
 	mtfsb0	4*cr7+lt	/* Disable FE_INEXACT exception */
 	fadds	fp1,fp1,fp13	/* x += TWO23 */
 	fsubs	fp1,fp1,fp13	/* x -= TWO23 */
 	fabs	fp1,fp1		/* if (x == 0.0) */
-	mtfsb0	4*cr1+eq	/* Clear pending FE_INEXACT exception */
+	mtfsf	0xff,fp11	/* Restore FE_INEXACT state.  */
 	blr			/* x = 0.0; */
 L(lessthanzero):
 	bgelr	cr7		/* if (x < 0.0) */
+	mffs	fp11
 	mtfsb0	4*cr7+lt	/* Disable FE_INEXACT exception */
 	fsubs	fp1,fp1,fp13	/* x -= TWO23 */
 	fadds	fp1,fp1,fp13	/* x += TWO23 */
 	fnabs	fp1,fp1		/* if (x == 0.0) */
-	mtfsb0	4*cr1+eq	/* Clear pending FE_INEXACT exception */
+	mtfsf	0xff,fp11	/* Restore FE_INEXACT state.  */
 	blr			/* x = -0.0; */
 END (__nearbyintf)
 

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |   14 +++++++
 math/Makefile                                      |    3 +-
 ...earbyint-except.c => test-nearbyint-except-2.c} |   38 +++++++------------
 sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S        |    6 ++-
 sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S       |    6 ++-
 sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S        |    6 ++-
 sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S       |    6 ++-
 7 files changed, 46 insertions(+), 33 deletions(-)
 copy math/{test-nearbyint-except.c => test-nearbyint-except-2.c} (64%)


hooks/post-receive
-- 
GNU C Library master sources



More information about the Glibc-cvs mailing list