]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
PowerPC: fix hypot/hypof FP exceptions
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>
Mon, 6 May 2013 19:40:17 +0000 (14:40 -0500)
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>
Mon, 6 May 2013 19:40:17 +0000 (14:40 -0500)
This patch fixes hypot/hypotf spurious floating-point exceptions
generate by internal operations.

ChangeLog
NEWS
math/libm-test.inc
sysdeps/powerpc/fpu/e_hypot.c
sysdeps/powerpc/fpu/e_hypotf.c

index 1c43908d626c674887e979dfaca015cadd662bd6..4bf30b6c57098fb00349c27febdbaa9f9cd7af98 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2013-05-06  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+       [BZ #15418]
+       [BZ #15419]
+       * sysdeps/powerpc/fpu/e_hypot.c: Fix spurious FP exception generated by
+       internal tests.
+       * sysdeps/powerpc/fpu/e_hypotf.c: Likewise.
+
 2013-05-06  Roland McGrath  <roland@hack.frob.com>
 
        * elf/dl-writev.h: New file.
diff --git a/NEWS b/NEWS
index ce654c1e5c9b12d913f2ce0333f69376f67ec21c..95a4e4f4c356e1cb537e7e7f01f60798bd5aa5f9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,7 +16,7 @@ Version 2.18
   15084, 15085, 15086, 15160, 15214, 15221, 15232, 15234, 15283, 15285,
   15287, 15304, 15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337,
   15342, 15346, 15361, 15366, 15380, 15394, 15405, 15406, 15409, 15416,
-  15423.
+  15418, 15419, 15423.
 
 * CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
   #15078).
index 4e1eb72919afb593d6c5dcb8ae4a761146538800..7afa46dba828b79db39b29db9c24c25eca207598 100644 (file)
@@ -9159,6 +9159,7 @@ hypot_test (void)
   TEST_ff_f (hypot, 0.75L, 1.25L, 1.45773797371132511771853821938639577L);
 
   TEST_ff_f (hypot, 1.0L, 0x1p-61L, 1.0L);
+  TEST_ff_f (hypot, 0x1p+0L, 0x1.fp-129L, 0x1p+0L);
 #if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
   TEST_ff_f (hypot, 0x1.23456789abcdef0123456789ab8p-500L, 0x1.23456789abcdef0123456789ab8p-500L, 4.9155782399407039128612180934736799735113e-151L);
 #endif
@@ -9170,6 +9171,7 @@ hypot_test (void)
 
 #if !defined TEST_FLOAT && !(defined TEST_DOUBLE && defined TEST_INLINE)
   TEST_ff_f (hypot, 0x3p1021L, 0x4p1021L, 0x5p1021L);
+  TEST_ff_f (hypot, 0x1p+0L, 0x0.3ep-1022L, 0x1p+0L);
 #endif
 
 #if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384 && !defined TEST_INLINE
index f23633946f6b3d520b29f17e2b490dc6330abbac..d8568d6e3f77d1187c1dcbb5d84e041d0a739162 100644 (file)
@@ -26,6 +26,7 @@ static const double two600  = 4.149515568880993e+180;
 static const double two1022 = 4.49423283715579e+307;
 static const double twoM500 = 3.054936363499605e-151;
 static const double twoM600 = 2.4099198651028841e-181;
+static const double two60factor = 1.5592502418239997e+290;
 static const double pdnum   = 2.225073858507201e-308;
 
 /* __ieee754_hypot(x,y)
@@ -87,9 +88,20 @@ __ieee754_hypot (double x, double y)
       x = y;
       y = t;
     }
-  if (y == 0.0 || (x / y) > two60)
+  if (y == 0.0)
+    return x;
+  /* if y is higher enough, y * 2^60 might overflow. The tests if
+     y >= 1.7976931348623157e+308/2^60 (two60factor) and uses the
+     appropriate check to avoid the overflow exception generation.  */
+  if (y > two60factor)
     {
-      return x + y;
+      if ((x / y) > two60)
+       return x + y;
+    }
+  else
+    {
+      if (x > (y * two60))
+       return x + y;
     }
   if (x > two500)
     {
index e97f0c35e39fd81b8bf818db3ab148e1a8ede136..93055afce55729c7c23b50b748c57768a276b41e 100644 (file)
@@ -69,22 +69,8 @@ static const float two30  = 1.0737418e09;
 float
 __ieee754_hypotf (float x, float y)
 {
-  x = fabsf (x);
-  y = fabsf (y);
-
   TEST_INF_NAN (x, y);
 
-  if (y > x)
-    {
-      float t = y;
-      y = x;
-      x = t;
-    }
-  if (y == 0.0 || (x / y) > two30)
-    {
-      return x + y;
-    }
-
   return __ieee754_sqrt ((double) x * x + (double) y * y);
 }
 strong_alias (__ieee754_hypotf, __hypotf_finite)