[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commits] r20933 - in /fsf/trunk/libc: ./ math/ sysdeps/ieee754/dbl-64/ sysdeps/ieee754/ldbl-128/ sysdeps/ieee754/ldbl-96/ sysdeps/spa...



Author: eglibc
Date: Sun Sep 30 00:01:48 2012
New Revision: 20933

Log:
Import glibc-mainline for 2012-09-30

Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/NEWS
    fsf/trunk/libc/math/libm-test.inc
    fsf/trunk/libc/sysdeps/ieee754/dbl-64/s_fma.c
    fsf/trunk/libc/sysdeps/ieee754/dbl-64/s_fmaf.c
    fsf/trunk/libc/sysdeps/ieee754/ldbl-128/s_fma.c
    fsf/trunk/libc/sysdeps/ieee754/ldbl-128/s_fmal.c
    fsf/trunk/libc/sysdeps/ieee754/ldbl-96/s_fma.c
    fsf/trunk/libc/sysdeps/ieee754/ldbl-96/s_fmal.c
    fsf/trunk/libc/sysdeps/sparc/fpu/libm-test-ulps

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sun Sep 30 00:01:48 2012
@@ -1,3 +1,25 @@
+2012-09-29  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	[BZ #14638]
+	* sysdeps/ieee754/dbl-64/s_fma.c (__fma): Use x * y + z for exact
+	0 + 0.
+	* sysdeps/ieee754/dbl-64/s_fmaf.c (__fmaf): Use original rounding
+	mode for addition resulting in exact zero.
+	* sysdeps/ieee754/ldbl-128/s_fma.c (__fma): Likewise.
+	* sysdeps/ieee754/ldbl-128/s_fmal.c (__fmal): Use x * y + z for
+	exact 0 + 0.
+	* sysdeps/ieee754/ldbl-96/s_fma.c (__fma): Likewise.
+	* sysdeps/ieee754/ldbl-96/s_fmal.c (__fmal): Likewise.
+	* math/libm-test.inc (fma_test): Add more tests.
+	(fma_test_towardzero): New function.
+	(fma_test_downward): Likewise.
+	(fma_test_upward): Likewise.
+	(main): Call the new functions.
+
+2012-09-28  David S. Miller  <davem@xxxxxxxxxxxxx>
+
+	* sysdeps/sparc/fpu/libm-test-ulps: Fix garbage in file.
+
 2012-09-28  Roland McGrath  <roland@xxxxxxxxxxxxx>
 
 	* sysdeps/posix/sleep.c (__sleep): Rewritten using __nanosleep

Modified: fsf/trunk/libc/NEWS
==============================================================================
--- fsf/trunk/libc/NEWS (original)
+++ fsf/trunk/libc/NEWS Sun Sep 30 00:01:48 2012
@@ -15,7 +15,7 @@
   14195, 14237, 14252, 14283, 14298, 14303, 14307, 14328, 14331, 14336,
   14337, 14347, 14349, 14376, 14459, 14476, 14505, 14510, 14516, 14518,
   14519, 14530, 14532, 14538, 14543, 14544, 14545, 14562, 14576, 14579,
-  14583, 14587, 14621.
+  14583, 14587, 14621, 14638.
 
 * Support for STT_GNU_IFUNC symbols added for s390 and s390x.
   Optimized versions of memcpy, memset, and memcmp added for System z10 and

Modified: fsf/trunk/libc/math/libm-test.inc
==============================================================================
--- fsf/trunk/libc/math/libm-test.inc (original)
+++ fsf/trunk/libc/math/libm-test.inc Sun Sep 30 00:01:48 2012
@@ -4546,6 +4546,36 @@
   TEST_fff_f (fma, minus_infty, minus_infty, plus_infty, plus_infty);
   TEST_fff_f (fma, plus_infty, minus_infty, minus_infty, minus_infty);
 
+  TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero);
+  TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero);
+  TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero);
+  TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero);
+  TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero);
+  TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero);
+  TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero);
+  TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero);
+  TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero);
+  TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero);
+  TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero);
+  TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero);
+  TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero);
+  TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero);
+  TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero);
+  TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero);
+  TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero);
+  TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero);
+  TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero);
+  TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero);
+  TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero);
+  TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero);
+  TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero);
+  TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero);
+
+  TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero);
+  TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero);
+  TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero);
+  TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero);
+
 #if defined (TEST_FLOAT) && FLT_MANT_DIG == 24
   TEST_fff_f (fma, 0x1.7ff8p+13, 0x1.000002p+0, 0x1.ffffp-24, 0x1.7ff802p+13);
   TEST_fff_f (fma, 0x1.fffp+0, 0x1.00001p+0, -0x1.fffp+0, 0x1.fffp-20);
@@ -4604,6 +4634,147 @@
 #endif
 
   END (fma);
+}
+
+
+static void
+fma_test_towardzero (void)
+{
+  int save_round_mode;
+  START (fma_towardzero);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_TOWARDZERO))
+    {
+      TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero);
+      TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero);
+      TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero);
+
+      TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero);
+      TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero);
+      TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero);
+      TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero);
+    }
+
+  fesetround (save_round_mode);
+
+  END (fma_towardzero);
+}
+
+
+static void
+fma_test_downward (void)
+{
+  int save_round_mode;
+  START (fma_downward);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_DOWNWARD))
+    {
+      TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, minus_zero);
+      TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, 1.0, plus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, 1.0, minus_zero, plus_zero, minus_zero);
+      TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, -1.0, plus_zero, plus_zero, minus_zero);
+      TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, -1.0, minus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, 1.0, minus_zero, minus_zero);
+      TEST_fff_f (fma, plus_zero, -1.0, plus_zero, minus_zero);
+      TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, 1.0, plus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, -1.0, minus_zero, minus_zero);
+
+      TEST_fff_f (fma, 1.0, 1.0, -1.0, minus_zero);
+      TEST_fff_f (fma, 1.0, -1.0, 1.0, minus_zero);
+      TEST_fff_f (fma, -1.0, 1.0, 1.0, minus_zero);
+      TEST_fff_f (fma, -1.0, -1.0, -1.0, minus_zero);
+    }
+
+  fesetround (save_round_mode);
+
+  END (fma_downward);
+}
+
+
+static void
+fma_test_upward (void)
+{
+  int save_round_mode;
+  START (fma_upward);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_UPWARD))
+    {
+      TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero);
+      TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero);
+      TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero);
+      TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero);
+      TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero);
+      TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero);
+      TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero);
+
+      TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero);
+      TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero);
+      TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero);
+      TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero);
+    }
+
+  fesetround (save_round_mode);
+
+  END (fma_upward);
 }
 
 
@@ -9539,6 +9710,9 @@
 
   /* Multiply and add:  */
   fma_test ();
+  fma_test_towardzero ();
+  fma_test_downward ();
+  fma_test_upward ();
 
   /* Complex functions:  */
   cabs_test ();

Modified: fsf/trunk/libc/sysdeps/ieee754/dbl-64/s_fma.c
==============================================================================
--- fsf/trunk/libc/sysdeps/ieee754/dbl-64/s_fma.c (original)
+++ fsf/trunk/libc/sysdeps/ieee754/dbl-64/s_fma.c Sun Sep 30 00:01:48 2012
@@ -128,6 +128,11 @@
       y = v.d;
       z = w.d;
     }
+
+  /* Ensure correct sign of exact 0 + 0.  */
+  if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
+    return x * y + z;
+
   /* Multiplication m1 + m2 = x * y using Dekker's algorithm.  */
 #define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
   double x1 = x * C;

Modified: fsf/trunk/libc/sysdeps/ieee754/dbl-64/s_fmaf.c
==============================================================================
--- fsf/trunk/libc/sysdeps/ieee754/dbl-64/s_fmaf.c (original)
+++ fsf/trunk/libc/sysdeps/ieee754/dbl-64/s_fmaf.c Sun Sep 30 00:01:48 2012
@@ -32,8 +32,15 @@
 __fmaf (float x, float y, float z)
 {
   fenv_t env;
+
   /* Multiplication is always exact.  */
   double temp = (double) x * (double) y;
+
+  /* Ensure correct sign of an exact zero result by performing the
+     addition in the original rounding mode in that case.  */
+  if (temp == -z)
+    return (float) temp + z;
+
   union ieee754_double u;
 
   libc_feholdexcept_setround (&env, FE_TOWARDZERO);

Modified: fsf/trunk/libc/sysdeps/ieee754/ldbl-128/s_fma.c
==============================================================================
--- fsf/trunk/libc/sysdeps/ieee754/ldbl-128/s_fma.c (original)
+++ fsf/trunk/libc/sysdeps/ieee754/ldbl-128/s_fma.c Sun Sep 30 00:01:48 2012
@@ -1,5 +1,5 @@
 /* Compute x * y + z as ternary operation.
-   Copyright (C) 2010 Free Software Foundation, Inc.
+   Copyright (C) 2010-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@xxxxxxxxxx>, 2010.
 
@@ -33,6 +33,12 @@
   fenv_t env;
   /* Multiplication is always exact.  */
   long double temp = (long double) x * (long double) y;
+
+  /* Ensure correct sign of an exact zero result by performing the
+     addition in the original rounding mode in that case.  */
+  if (temp == -z)
+    return (double) temp + z;
+
   union ieee854_long_double u;
   feholdexcept (&env);
   fesetround (FE_TOWARDZERO);

Modified: fsf/trunk/libc/sysdeps/ieee754/ldbl-128/s_fmal.c
==============================================================================
--- fsf/trunk/libc/sysdeps/ieee754/ldbl-128/s_fmal.c (original)
+++ fsf/trunk/libc/sysdeps/ieee754/ldbl-128/s_fmal.c Sun Sep 30 00:01:48 2012
@@ -129,6 +129,11 @@
       y = v.d;
       z = w.d;
     }
+
+  /* Ensure correct sign of exact 0 + 0.  */
+  if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
+    return x * y + z;
+
   /* Multiplication m1 + m2 = x * y using Dekker's algorithm.  */
 #define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
   long double x1 = x * C;

Modified: fsf/trunk/libc/sysdeps/ieee754/ldbl-96/s_fma.c
==============================================================================
--- fsf/trunk/libc/sysdeps/ieee754/ldbl-96/s_fma.c (original)
+++ fsf/trunk/libc/sysdeps/ieee754/ldbl-96/s_fma.c Sun Sep 30 00:01:48 2012
@@ -1,5 +1,5 @@
 /* Compute x * y + z as ternary operation.
-   Copyright (C) 2010 Free Software Foundation, Inc.
+   Copyright (C) 2010-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@xxxxxxxxxx>, 2010.
 
@@ -37,6 +37,10 @@
 	return (z + x) + y;
       return (x * y) + z;
     }
+
+  /* Ensure correct sign of exact 0 + 0.  */
+  if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
+    return x * y + z;
 
   /* Multiplication m1 + m2 = x * y using Dekker's algorithm.  */
 #define C ((1ULL << (LDBL_MANT_DIG + 1) / 2) + 1)

Modified: fsf/trunk/libc/sysdeps/ieee754/ldbl-96/s_fmal.c
==============================================================================
--- fsf/trunk/libc/sysdeps/ieee754/ldbl-96/s_fmal.c (original)
+++ fsf/trunk/libc/sysdeps/ieee754/ldbl-96/s_fmal.c Sun Sep 30 00:01:48 2012
@@ -129,6 +129,11 @@
       y = v.d;
       z = w.d;
     }
+
+  /* Ensure correct sign of exact 0 + 0.  */
+  if (__builtin_expect ((x == 0 || y == 0) && z == 0, 0))
+    return x * y + z;
+
   /* Multiplication m1 + m2 = x * y using Dekker's algorithm.  */
 #define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
   long double x1 = x * C;

Modified: fsf/trunk/libc/sysdeps/sparc/fpu/libm-test-ulps
==============================================================================
--- fsf/trunk/libc/sysdeps/sparc/fpu/libm-test-ulps (original)
+++ fsf/trunk/libc/sysdeps/sparc/fpu/libm-test-ulps Sun Sep 30 00:01:48 2012
@@ -1327,10 +1327,9 @@
 Test "Imaginary part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
 double: 1
 idouble: 1
-Test "Imaginary part of: clog10 (0xfd95243681c055c2632286921092p-113 + 0x1bccabcd29ca2152860ec29e34ef7p-113 i) == 2.8774482675253468630312378575186855052697e-66 + 0.4571561610046221605554903008571429975493 ?":
-ildouble: 2
 Test "Imaginary part of: clog10 (0xfd95243681c055c2632286921092p-113 + 0x1bccabcd29ca2152860ec29e34ef7p-113 i) == 2.8774482675253468630312378575186855052697e-66 + 0.4571561610046221605554903008571429975493 i":
 ldouble: 2
+ildouble: 2
 Test "Imaginary part of: clog10 (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 2.3329549194675052736016290082882121135546e-26 + 0.4561756099441139182878993697611751382976 i":
 double: 1
 idouble: 1

_______________________________________________
Commits mailing list
Commits@xxxxxxxxxx
http://eglibc.org/cgi-bin/mailman/listinfo/commits