summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--math/libm-test.inc52
-rw-r--r--sysdeps/ieee754/dbl-64/e_hypot.c2
-rw-r--r--sysdeps/ieee754/flt-32/e_hypotf.c4
-rw-r--r--sysdeps/ieee754/ldbl-128/e_hypotl.c2
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/e_hypotl.c2
-rw-r--r--sysdeps/ieee754/ldbl-96/e_hypotl.c2
-rw-r--r--sysdeps/powerpc/fpu/e_hypot.c10
-rw-r--r--sysdeps/powerpc/fpu/e_hypotf.c10
9 files changed, 91 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index ab723ebfbb..039bba6657 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2016-12-07 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #20940]
+ * sysdeps/ieee754/dbl-64/e_hypot.c (__ieee754_hypot): Do not
+ return Inf for arguments Inf and sNaN.
+ * sysdeps/ieee754/flt-32/e_hypotf.c (__ieee754_hypotf): Likewise.
+ * sysdeps/ieee754/ldbl-128/e_hypotl.c (__ieee754_hypotl):
+ Likewise.
+ * sysdeps/ieee754/ldbl-128ibm/e_hypotl.c (__ieee754_hypotl):
+ Likewise.
+ * sysdeps/ieee754/ldbl-96/e_hypotl.c (__ieee754_hypotl): Likewise.
+ * sysdeps/powerpc/fpu/e_hypot.c (TEST_INF_NAN): Do not return Inf
+ for arguments Inf and sNaN. When returning a NaN, compute it by
+ arithmetic on the arguments.
+ * sysdeps/powerpc/fpu/e_hypotf.c (TEST_INF_NAN): Likewise.
+ * math/libm-test.inc (pow_test_data): Add tests of sNaN arguments.
+
2016-12-06 Joseph Myers <joseph@codesourcery.com>
[BZ #20916]
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 9123dcfc48..e973a3f6ae 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -8344,6 +8344,14 @@ static const struct test_ff_f_data hypot_test_data[] =
TEST_ff_f (hypot, -qnan_value, plus_infty, plus_infty, ERRNO_UNCHANGED|NO_TEST_INLINE),
TEST_ff_f (hypot, qnan_value, minus_infty, plus_infty, ERRNO_UNCHANGED|NO_TEST_INLINE),
TEST_ff_f (hypot, -qnan_value, minus_infty, plus_infty, ERRNO_UNCHANGED|NO_TEST_INLINE),
+ TEST_ff_f (hypot, plus_infty, snan_value, qnan_value, INVALID_EXCEPTION|NO_TEST_INLINE),
+ TEST_ff_f (hypot, plus_infty, -snan_value, qnan_value, INVALID_EXCEPTION|NO_TEST_INLINE),
+ TEST_ff_f (hypot, minus_infty, snan_value, qnan_value, INVALID_EXCEPTION|NO_TEST_INLINE),
+ TEST_ff_f (hypot, minus_infty, -snan_value, qnan_value, INVALID_EXCEPTION|NO_TEST_INLINE),
+ TEST_ff_f (hypot, snan_value, plus_infty, qnan_value, INVALID_EXCEPTION|NO_TEST_INLINE),
+ TEST_ff_f (hypot, -snan_value, plus_infty, qnan_value, INVALID_EXCEPTION|NO_TEST_INLINE),
+ TEST_ff_f (hypot, snan_value, minus_infty, qnan_value, INVALID_EXCEPTION|NO_TEST_INLINE),
+ TEST_ff_f (hypot, -snan_value, minus_infty, qnan_value, INVALID_EXCEPTION|NO_TEST_INLINE),
TEST_ff_f (hypot, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, 0, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -8361,6 +8369,22 @@ static const struct test_ff_f_data hypot_test_data[] =
TEST_ff_f (hypot, min_subnorm_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, -min_subnorm_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, -min_subnorm_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (hypot, 0, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, 0, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, minus_zero, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, minus_zero, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, max_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, max_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -max_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -max_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, min_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, min_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -min_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -min_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, min_subnorm_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, min_subnorm_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -min_subnorm_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -min_subnorm_value, -snan_value, qnan_value, INVALID_EXCEPTION),
TEST_ff_f (hypot, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, -qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, qnan_value, minus_zero, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -8377,11 +8401,39 @@ static const struct test_ff_f_data hypot_test_data[] =
TEST_ff_f (hypot, -qnan_value, min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, qnan_value, -min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, -qnan_value, -min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (hypot, snan_value, 0, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, 0, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, minus_zero, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, minus_zero, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, max_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, max_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, -max_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, -max_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, min_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, min_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, -min_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, -min_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, -min_subnorm_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, -min_subnorm_value, qnan_value, INVALID_EXCEPTION),
TEST_ff_f (hypot, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, -qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (hypot, -qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (hypot, qnan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, qnan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -qnan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -qnan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, qnan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, -qnan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, qnan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, -qnan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, snan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, snan_value, qnan_value, INVALID_EXCEPTION),
+ TEST_ff_f (hypot, -snan_value, -snan_value, qnan_value, INVALID_EXCEPTION),
AUTO_TESTS_ff_f (hypot),
};
diff --git a/sysdeps/ieee754/dbl-64/e_hypot.c b/sysdeps/ieee754/dbl-64/e_hypot.c
index f142c450a2..76eb408348 100644
--- a/sysdeps/ieee754/dbl-64/e_hypot.c
+++ b/sysdeps/ieee754/dbl-64/e_hypot.c
@@ -76,6 +76,8 @@ __ieee754_hypot (double x, double y)
{
u_int32_t low;
w = a + b; /* for sNaN */
+ if (issignaling (a) || issignaling (b))
+ return w;
GET_LOW_WORD (low, a);
if (((ha & 0xfffff) | low) == 0)
w = a;
diff --git a/sysdeps/ieee754/flt-32/e_hypotf.c b/sysdeps/ieee754/flt-32/e_hypotf.c
index 717b82e42f..fda2651a84 100644
--- a/sysdeps/ieee754/flt-32/e_hypotf.c
+++ b/sysdeps/ieee754/flt-32/e_hypotf.c
@@ -26,9 +26,9 @@ __ieee754_hypotf(float x, float y)
ha &= 0x7fffffff;
GET_FLOAT_WORD(hb,y);
hb &= 0x7fffffff;
- if (ha == 0x7f800000)
+ if (ha == 0x7f800000 && !issignaling (y))
return fabsf(x);
- else if (hb == 0x7f800000)
+ else if (hb == 0x7f800000 && !issignaling (x))
return fabsf(y);
else if (ha > 0x7f800000 || hb > 0x7f800000)
return fabsf(x) * fabsf(y);
diff --git a/sysdeps/ieee754/ldbl-128/e_hypotl.c b/sysdeps/ieee754/ldbl-128/e_hypotl.c
index a93f5a4c8f..6c4e178fbe 100644
--- a/sysdeps/ieee754/ldbl-128/e_hypotl.c
+++ b/sysdeps/ieee754/ldbl-128/e_hypotl.c
@@ -67,6 +67,8 @@ __ieee754_hypotl(_Float128 x, _Float128 y)
if(ha >= 0x7fff000000000000LL) { /* Inf or NaN */
u_int64_t low;
w = a+b; /* for sNaN */
+ if (issignaling (a) || issignaling (b))
+ return w;
GET_LDOUBLE_LSW64(low,a);
if(((ha&0xffffffffffffLL)|low)==0) w = a;
GET_LDOUBLE_LSW64(low,b);
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c b/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
index c68dac03b0..de5a66ab05 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c
@@ -67,6 +67,8 @@ __ieee754_hypotl(long double x, long double y)
if(ha > 0x5f30000000000000LL) { /* a>2**500 */
if(ha >= 0x7ff0000000000000LL) { /* Inf or NaN */
w = a+b; /* for sNaN */
+ if (issignaling (a) || issignaling (b))
+ return w;
if(ha == 0x7ff0000000000000LL)
w = a;
if(hb == 0x7ff0000000000000LL)
diff --git a/sysdeps/ieee754/ldbl-96/e_hypotl.c b/sysdeps/ieee754/ldbl-96/e_hypotl.c
index ee3a07055b..6b55b6d8ee 100644
--- a/sysdeps/ieee754/ldbl-96/e_hypotl.c
+++ b/sysdeps/ieee754/ldbl-96/e_hypotl.c
@@ -68,6 +68,8 @@ long double __ieee754_hypotl(long double x, long double y)
u_int32_t exp __attribute__ ((unused));
u_int32_t high,low;
w = a+b; /* for sNaN */
+ if (issignaling (a) || issignaling (b))
+ return w;
GET_LDOUBLE_WORDS(exp,high,low,a);
if(((high&0x7fffffff)|low)==0) w = a;
GET_LDOUBLE_WORDS(exp,high,low,b);
diff --git a/sysdeps/powerpc/fpu/e_hypot.c b/sysdeps/powerpc/fpu/e_hypot.c
index da0f2daed3..65314c6ff5 100644
--- a/sysdeps/powerpc/fpu/e_hypot.c
+++ b/sysdeps/powerpc/fpu/e_hypot.c
@@ -41,10 +41,11 @@ static const double pdnum = 2.225073858507201e-308;
#ifdef _ARCH_PWR7
/* POWER7 isinf and isnan optimization are fast. */
# define TEST_INF_NAN(x, y) \
- if (isinf(x) || isinf(y)) \
+ if ((isinf(x) || isinf(y)) \
+ && !issignaling (x) && !issignaling (y)) \
return INFINITY; \
if (isnan(x) || isnan(y)) \
- return NAN;
+ return x + y;
# else
/* For POWER6 and below isinf/isnan triggers LHS and PLT calls are
* costly (especially for POWER6). */
@@ -66,9 +67,10 @@ static const double pdnum = 2.225073858507201e-308;
uint32_t ht = hx; hx = hy; hy = ht; \
} \
if (hx >= 0x7ff00000) { \
- if (hx == 0x7ff00000 || hy == 0x7ff00000) \
+ if ((hx == 0x7ff00000 || hy == 0x7ff00000) \
+ && !issignaling (x) && !issignaling (y)) \
return INFINITY; \
- return NAN; \
+ return x + y; \
} \
} while (0)
diff --git a/sysdeps/powerpc/fpu/e_hypotf.c b/sysdeps/powerpc/fpu/e_hypotf.c
index 48360828c3..c18281503c 100644
--- a/sysdeps/powerpc/fpu/e_hypotf.c
+++ b/sysdeps/powerpc/fpu/e_hypotf.c
@@ -31,10 +31,11 @@
#ifdef _ARCH_PWR7
/* POWER7 isinf and isnan optimizations are fast. */
# define TEST_INF_NAN(x, y) \
- if (isinff(x) || isinff(y)) \
+ if ((isinff(x) || isinff(y)) \
+ && !issignaling (x) && !issignaling (y)) \
return INFINITY; \
if (isnanf(x) || isnanf(y)) \
- return NAN;
+ return x + y;
# else
/* For POWER6 and below isinf/isnan triggers LHS and PLT calls are
* costly (especially for POWER6). */
@@ -56,9 +57,10 @@
uint32_t ht = hx; hx = hy; hy = ht; \
} \
if (hx >= 0x7f800000) { \
- if (hx == 0x7f800000 || hy == 0x7f800000) \
+ if ((hx == 0x7f800000 || hy == 0x7f800000) \
+ && !issignaling (x) && !issignaling (y)) \
return INFINITY; \
- return NAN; \
+ return x + y; \
} \
} while (0)
#endif