From 16e616a72f9ac247520c0c7da99b99e229facdf9 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 6 May 2013 14:40:17 -0500 Subject: [PATCH] PowerPC: fix hypot/hypof FP exceptions This patch fixes hypot/hypotf spurious floating-point exceptions generate by internal operations. --- ChangeLog | 8 ++++++++ NEWS | 2 +- math/libm-test.inc | 2 ++ sysdeps/powerpc/fpu/e_hypot.c | 16 ++++++++++++++-- sysdeps/powerpc/fpu/e_hypotf.c | 14 -------------- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1c43908d626..4bf30b6c570 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-05-06 Adhemerval Zanella + + [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 * elf/dl-writev.h: New file. diff --git a/NEWS b/NEWS index ce654c1e5c9..95a4e4f4c35 100644 --- 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). diff --git a/math/libm-test.inc b/math/libm-test.inc index 4e1eb72919a..7afa46dba82 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -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 diff --git a/sysdeps/powerpc/fpu/e_hypot.c b/sysdeps/powerpc/fpu/e_hypot.c index f23633946f6..d8568d6e3f7 100644 --- a/sysdeps/powerpc/fpu/e_hypot.c +++ b/sysdeps/powerpc/fpu/e_hypot.c @@ -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) { diff --git a/sysdeps/powerpc/fpu/e_hypotf.c b/sysdeps/powerpc/fpu/e_hypotf.c index e97f0c35e39..93055afce55 100644 --- a/sysdeps/powerpc/fpu/e_hypotf.c +++ b/sysdeps/powerpc/fpu/e_hypotf.c @@ -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) -- 2.47.2