summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-05-19 15:35:29 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-05-19 15:35:29 +0000
commite0b16cc25c4bae1ac45ec6ce90341f9a7d1ae6b6 (patch)
tree82c8f2f5c13fba98b2b028475bf84d9cd15bd6b8
parentf66f0ce833523a47e12b4a3eacab6b20866ab033 (diff)
downloadglibc-e0b16cc25c4bae1ac45ec6ce90341f9a7d1ae6b6.tar.gz
glibc-e0b16cc25c4bae1ac45ec6ce90341f9a7d1ae6b6.tar.xz
glibc-e0b16cc25c4bae1ac45ec6ce90341f9a7d1ae6b6.zip
Fix ccos, csin, ccosh, csinh overflows (bug 14123).
-rw-r--r--ChangeLog21
-rw-r--r--NEWS2
-rw-r--r--math/libm-test.inc124
-rw-r--r--math/s_ccosh.c43
-rw-r--r--math/s_ccoshf.c43
-rw-r--r--math/s_ccoshl.c43
-rw-r--r--math/s_csin.c43
-rw-r--r--math/s_csinf.c43
-rw-r--r--math/s_csinh.c43
-rw-r--r--math/s_csinhf.c43
-rw-r--r--math/s_csinhl.c43
-rw-r--r--math/s_csinl.c43
-rw-r--r--sysdeps/i386/fpu/libm-test-ulps217
-rw-r--r--sysdeps/x86_64/fpu/libm-test-ulps114
14 files changed, 801 insertions, 64 deletions
diff --git a/ChangeLog b/ChangeLog
index 8680123faf..9fda91d7d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2012-05-19  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #14123]
+	* math/s_ccosh.c: Include <float.h>
+	(__ccosh): Avoid internal overflow calculating sinh and cosh
+	values before multiplying by sin and cos values.
+	* math/s_ccoshf.c: Likewise.
+	* math/s_ccoshl.c: Likewise.
+	* math/s_csin.c: Likewise.
+	* math/s_csinf.c: Likewise.
+	* math/s_csinl.c: Likewise.
+	* math/s_csinh.c: Likewise.
+	* math/s_csinhf.c: Likewise.
+	* math/s_csinhl.c: Likewise.
+	* math/libm-test.inc (ccos_test): Add more tests.
+	(ccosh_test): Likewise.
+	(csin_test): Likewise.
+	(csinh_test): Likewise.
+	* sysdeps/i386/fpu/libm-test-ulps: Update.
+	* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
 2012-05-19  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* sysdeps/unix/sysv/linux/wordsize-64/preadv.c: New file.
diff --git a/NEWS b/NEWS
index 48ceada32f..5bc3dd9459 100644
--- a/NEWS
+++ b/NEWS
@@ -27,7 +27,7 @@ Version 2.16
   13919, 13920, 13921, 13922, 13923, 13924, 13926, 13927, 13928, 13938,
   13941, 13942, 13954, 13955, 13956, 13963, 13967, 13970, 13973, 13979,
   13983, 13986, 14012, 14027, 14033, 14034, 14040, 14043, 14044, 14049,
-  14053, 14055, 14059, 14064, 14080, 14083, 14103, 14104, 14109
+  14053, 14055, 14059, 14064, 14080, 14083, 14103, 14104, 14109, 14123
 
 * ISO C11 support:
 
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 47bbd5f1ef..19c3c8ae3f 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -1955,6 +1955,37 @@ ccos_test (void)
   TEST_c_c (ccos, 0.75L, 1.25L, 1.38173873063425888530729933139078645L, -1.09193013555397466170919531722024128L);
   TEST_c_c (ccos, -2, -3, -4.18962569096880723013255501961597373L, -9.10922789375533659797919726277886212L);
 
+  TEST_c_c (ccos, 0.75, 89.5, 2.708024460708609732016532185663087200560e38L, -2.522786001038096774676288412995370563339e38L);
+  TEST_c_c (ccos, 0.75, -89.5, 2.708024460708609732016532185663087200560e38L, 2.522786001038096774676288412995370563339e38L);
+  TEST_c_c (ccos, -0.75, 89.5, 2.708024460708609732016532185663087200560e38L, 2.522786001038096774676288412995370563339e38L);
+  TEST_c_c (ccos, -0.75, -89.5, 2.708024460708609732016532185663087200560e38L, -2.522786001038096774676288412995370563339e38L);
+
+#ifndef TEST_FLOAT
+  TEST_c_c (ccos, 0.75, 710.5, 1.347490911916428129246890157395342279438e308L, -1.255317763348154410745082950806112487736e308L);
+  TEST_c_c (ccos, 0.75, -710.5, 1.347490911916428129246890157395342279438e308L, 1.255317763348154410745082950806112487736e308L);
+  TEST_c_c (ccos, -0.75, 710.5, 1.347490911916428129246890157395342279438e308L, 1.255317763348154410745082950806112487736e308L);
+  TEST_c_c (ccos, -0.75, -710.5, 1.347490911916428129246890157395342279438e308L, -1.255317763348154410745082950806112487736e308L);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+  TEST_c_c (ccos, 0.75, 11357.25, 9.001213196851067077465606717616495588201e4931L, -8.385498349388321535962327491346664141020e4931L);
+  TEST_c_c (ccos, 0.75, -11357.25, 9.001213196851067077465606717616495588201e4931L, 8.385498349388321535962327491346664141020e4931L);
+  TEST_c_c (ccos, -0.75, 11357.25, 9.001213196851067077465606717616495588201e4931L, 8.385498349388321535962327491346664141020e4931L);
+  TEST_c_c (ccos, -0.75, -11357.25, 9.001213196851067077465606717616495588201e4931L, -8.385498349388321535962327491346664141020e4931L);
+#endif
+
+#ifdef TEST_FLOAT
+  TEST_c_c (ccos, 0x1p-149, 180, plus_infty, -1.043535896672617552965983803453927655332e33L, OVERFLOW_EXCEPTION);
+#endif
+
+#if defined TEST_DOUBLE || (defined TEST_LDOUBLE && LDBL_MAX_EXP == 1024)
+  TEST_c_c (ccos, 0x1p-1074, 1440, plus_infty, -5.981479269486130556466515778180916082415e301L, OVERFLOW_EXCEPTION);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+  TEST_c_c (ccos, 0x1p-16434L, 22730, plus_infty, -1.217853148905605987081057582351152052687e4924L, OVERFLOW_EXCEPTION);
+#endif
+
   END (ccos, complex);
 }
 
@@ -2024,6 +2055,37 @@ ccosh_test (void)
 
   TEST_c_c (ccosh, -2, -3, -3.72454550491532256547397070325597253L, 0.511822569987384608834463849801875634L);
 
+  TEST_c_c (ccosh, 89.5, 0.75, 2.708024460708609732016532185663087200560e38L, 2.522786001038096774676288412995370563339e38L);
+  TEST_c_c (ccosh, -89.5, 0.75, 2.708024460708609732016532185663087200560e38L, -2.522786001038096774676288412995370563339e38L);
+  TEST_c_c (ccosh, 89.5, -0.75, 2.708024460708609732016532185663087200560e38L, -2.522786001038096774676288412995370563339e38L);
+  TEST_c_c (ccosh, -89.5, -0.75, 2.708024460708609732016532185663087200560e38L, 2.522786001038096774676288412995370563339e38L);
+
+#ifndef TEST_FLOAT
+  TEST_c_c (ccosh, 710.5, 0.75, 1.347490911916428129246890157395342279438e308L, 1.255317763348154410745082950806112487736e308L);
+  TEST_c_c (ccosh, -710.5, 0.75, 1.347490911916428129246890157395342279438e308L, -1.255317763348154410745082950806112487736e308L);
+  TEST_c_c (ccosh, 710.5, -0.75, 1.347490911916428129246890157395342279438e308L, -1.255317763348154410745082950806112487736e308L);
+  TEST_c_c (ccosh, -710.5, -0.75, 1.347490911916428129246890157395342279438e308L, 1.255317763348154410745082950806112487736e308L);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+  TEST_c_c (ccosh, 11357.25, 0.75, 9.001213196851067077465606717616495588201e4931L, 8.385498349388321535962327491346664141020e4931L);
+  TEST_c_c (ccosh, -11357.25, 0.75, 9.001213196851067077465606717616495588201e4931L, -8.385498349388321535962327491346664141020e4931L);
+  TEST_c_c (ccosh, 11357.25, -0.75, 9.001213196851067077465606717616495588201e4931L, -8.385498349388321535962327491346664141020e4931L);
+  TEST_c_c (ccosh, -11357.25, -0.75, 9.001213196851067077465606717616495588201e4931L, 8.385498349388321535962327491346664141020e4931L);
+#endif
+
+#ifdef TEST_FLOAT
+  TEST_c_c (ccosh, 180, 0x1p-149, plus_infty, 1.043535896672617552965983803453927655332e33L, OVERFLOW_EXCEPTION);
+#endif
+
+#if defined TEST_DOUBLE || (defined TEST_LDOUBLE && LDBL_MAX_EXP == 1024)
+  TEST_c_c (ccosh, 1440, 0x1p-1074, plus_infty, 5.981479269486130556466515778180916082415e301L, OVERFLOW_EXCEPTION);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+  TEST_c_c (ccosh, 22730, 0x1p-16434L, plus_infty, 1.217853148905605987081057582351152052687e4924L, OVERFLOW_EXCEPTION);
+#endif
+
   END (ccosh, complex);
 }
 
@@ -2908,6 +2970,37 @@ csin_test (void)
   TEST_c_c (csin, 0.75L, 1.25L, 1.28722291002649188575873510790565441L, 1.17210635989270256101081285116138863L);
   TEST_c_c (csin, -2, -3, -9.15449914691142957346729954460983256L, 4.16890695996656435075481305885375484L);
 
+  TEST_c_c (csin, 0.75, 89.5, 2.522786001038096774676288412995370563339e38L, 2.708024460708609732016532185663087200560e38L);
+  TEST_c_c (csin, 0.75, -89.5, 2.522786001038096774676288412995370563339e38L, -2.708024460708609732016532185663087200560e38L);
+  TEST_c_c (csin, -0.75, 89.5, -2.522786001038096774676288412995370563339e38L, 2.708024460708609732016532185663087200560e38L);
+  TEST_c_c (csin, -0.75, -89.5, -2.522786001038096774676288412995370563339e38L, -2.708024460708609732016532185663087200560e38L);
+
+#ifndef TEST_FLOAT
+  TEST_c_c (csin, 0.75, 710.5, 1.255317763348154410745082950806112487736e308L, 1.347490911916428129246890157395342279438e308L);
+  TEST_c_c (csin, 0.75, -710.5, 1.255317763348154410745082950806112487736e308L, -1.347490911916428129246890157395342279438e308L);
+  TEST_c_c (csin, -0.75, 710.5, -1.255317763348154410745082950806112487736e308L, 1.347490911916428129246890157395342279438e308L);
+  TEST_c_c (csin, -0.75, -710.5, -1.255317763348154410745082950806112487736e308L, -1.347490911916428129246890157395342279438e308L);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+  TEST_c_c (csin, 0.75, 11357.25, 8.385498349388321535962327491346664141020e4931L, 9.001213196851067077465606717616495588201e4931L);
+  TEST_c_c (csin, 0.75, -11357.25, 8.385498349388321535962327491346664141020e4931L, -9.001213196851067077465606717616495588201e4931L);
+  TEST_c_c (csin, -0.75, 11357.25, -8.385498349388321535962327491346664141020e4931L, 9.001213196851067077465606717616495588201e4931L);
+  TEST_c_c (csin, -0.75, -11357.25, -8.385498349388321535962327491346664141020e4931L, -9.001213196851067077465606717616495588201e4931L);
+#endif
+
+#ifdef TEST_FLOAT
+  TEST_c_c (csin, 0x1p-149, 180, 1.043535896672617552965983803453927655332e33L, plus_infty, OVERFLOW_EXCEPTION);
+#endif
+
+#if defined TEST_DOUBLE || (defined TEST_LDOUBLE && LDBL_MAX_EXP == 1024)
+  TEST_c_c (csin, 0x1p-1074, 1440, 5.981479269486130556466515778180916082415e301L, plus_infty, OVERFLOW_EXCEPTION);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+  TEST_c_c (csin, 0x1p-16434L, 22730, 1.217853148905605987081057582351152052687e4924L, plus_infty, OVERFLOW_EXCEPTION);
+#endif
+
   END (csin, complex);
 }
 
@@ -2976,6 +3069,37 @@ csinh_test (void)
   TEST_c_c (csinh, 0.75L, 1.25L, 0.259294854551162779153349830618433028L, 1.22863452409509552219214606515777594L);
   TEST_c_c (csinh, -2, -3, 3.59056458998577995201256544779481679L, -0.530921086248519805267040090660676560L);
 
+  TEST_c_c (csinh, 89.5, 0.75, 2.708024460708609732016532185663087200560e38L, 2.522786001038096774676288412995370563339e38L);
+  TEST_c_c (csinh, -89.5, 0.75, -2.708024460708609732016532185663087200560e38L, 2.522786001038096774676288412995370563339e38L);
+  TEST_c_c (csinh, 89.5, -0.75, 2.708024460708609732016532185663087200560e38L, -2.522786001038096774676288412995370563339e38L);
+  TEST_c_c (csinh, -89.5, -0.75, -2.708024460708609732016532185663087200560e38L, -2.522786001038096774676288412995370563339e38L);
+
+#ifndef TEST_FLOAT
+  TEST_c_c (csinh, 710.5, 0.75, 1.347490911916428129246890157395342279438e308L, 1.255317763348154410745082950806112487736e308L);
+  TEST_c_c (csinh, -710.5, 0.75, -1.347490911916428129246890157395342279438e308L, 1.255317763348154410745082950806112487736e308L);
+  TEST_c_c (csinh, 710.5, -0.75, 1.347490911916428129246890157395342279438e308L, -1.255317763348154410745082950806112487736e308L);
+  TEST_c_c (csinh, -710.5, -0.75, -1.347490911916428129246890157395342279438e308L, -1.255317763348154410745082950806112487736e308L);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+  TEST_c_c (csinh, 11357.25, 0.75, 9.001213196851067077465606717616495588201e4931L, 8.385498349388321535962327491346664141020e4931L);
+  TEST_c_c (csinh, -11357.25, 0.75, -9.001213196851067077465606717616495588201e4931L, 8.385498349388321535962327491346664141020e4931L);
+  TEST_c_c (csinh, 11357.25, -0.75, 9.001213196851067077465606717616495588201e4931L, -8.385498349388321535962327491346664141020e4931L);
+  TEST_c_c (csinh, -11357.25, -0.75, -9.001213196851067077465606717616495588201e4931L, -8.385498349388321535962327491346664141020e4931L);
+#endif
+
+#ifdef TEST_FLOAT
+  TEST_c_c (csinh, 180, 0x1p-149, plus_infty, 1.043535896672617552965983803453927655332e33L, OVERFLOW_EXCEPTION);
+#endif
+
+#if defined TEST_DOUBLE || (defined TEST_LDOUBLE && LDBL_MAX_EXP == 1024)
+  TEST_c_c (csinh, 1440, 0x1p-1074, plus_infty, 5.981479269486130556466515778180916082415e301L, OVERFLOW_EXCEPTION);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+  TEST_c_c (csinh, 22730, 0x1p-16434L, plus_infty, 1.217853148905605987081057582351152052687e4924L, OVERFLOW_EXCEPTION);
+#endif
+
   END (csinh, complex);
 }
 
diff --git a/math/s_ccosh.c b/math/s_ccosh.c
index 2c2b71ceab..44c9944466 100644
--- a/math/s_ccosh.c
+++ b/math/s_ccosh.c
@@ -1,5 +1,5 @@
 /* Complex cosine hyperbole function for double.
-   Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,9 +20,8 @@
 #include <complex.h>
 #include <fenv.h>
 #include <math.h>
-
 #include <math_private.h>
-
+#include <float.h>
 
 __complex__ double
 __ccosh (__complex__ double x)
@@ -37,14 +36,44 @@ __ccosh (__complex__ double x)
       if (__builtin_expect (icls >= FP_ZERO, 1))
 	{
 	  /* Imaginary part is finite.  */
-	  double sinh_val = __ieee754_sinh (__real__ x);
-	  double cosh_val = __ieee754_cosh (__real__ x);
+	  const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
 	  double sinix, cosix;
 
 	  __sincos (__imag__ x, &sinix, &cosix);
 
-	  __real__ retval = cosh_val * cosix;
-	  __imag__ retval = sinh_val * sinix;
+	  if (fabs (__real__ x) > t)
+	    {
+	      double exp_t = __ieee754_exp (t);
+	      double rx = fabs (__real__ x);
+	      if (signbit (__real__ x))
+		sinix = -sinix;
+	      rx -= t;
+	      sinix *= exp_t / 2.0;
+	      cosix *= exp_t / 2.0;
+	      if (rx > t)
+		{
+		  rx -= t;
+		  sinix *= exp_t;
+		  cosix *= exp_t;
+		}
+	      if (rx > t)
+		{
+		  /* Overflow (original real part of x > 3t).  */
+		  __real__ retval = DBL_MAX * cosix;
+		  __imag__ retval = DBL_MAX * sinix;
+		}
+	      else
+		{
+		  double exp_val = __ieee754_exp (rx);
+		  __real__ retval = exp_val * cosix;
+		  __imag__ retval = exp_val * sinix;
+		}
+	    }
+	  else
+	    {
+	      __real__ retval = __ieee754_cosh (__real__ x) * cosix;
+	      __imag__ retval = __ieee754_sinh (__real__ x) * sinix;
+	    }
 	}
       else
 	{
diff --git a/math/s_ccoshf.c b/math/s_ccoshf.c
index a5a12c13e3..d6f811049e 100644
--- a/math/s_ccoshf.c
+++ b/math/s_ccoshf.c
@@ -1,5 +1,5 @@
 /* Complex cosine hyperbole function for float.
-   Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,9 +20,8 @@
 #include <complex.h>
 #include <fenv.h>
 #include <math.h>
-
 #include <math_private.h>
-
+#include <float.h>
 
 __complex__ float
 __ccoshf (__complex__ float x)
@@ -37,14 +36,44 @@ __ccoshf (__complex__ float x)
       if (__builtin_expect (icls >= FP_ZERO, 1))
 	{
 	  /* Imaginary part is finite.  */
-	  float sinh_val = __ieee754_sinhf (__real__ x);
-	  float cosh_val = __ieee754_coshf (__real__ x);
+	  const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2);
 	  float sinix, cosix;
 
 	  __sincosf (__imag__ x, &sinix, &cosix);
 
-	  __real__ retval = cosh_val * cosix;
-	  __imag__ retval = sinh_val * sinix;
+	  if (fabsf (__real__ x) > t)
+	    {
+	      float exp_t = __ieee754_expf (t);
+	      float rx = fabsf (__real__ x);
+	      if (signbit (__real__ x))
+		sinix = -sinix;
+	      rx -= t;
+	      sinix *= exp_t / 2.0f;
+	      cosix *= exp_t / 2.0f;
+	      if (rx > t)
+		{
+		  rx -= t;
+		  sinix *= exp_t;
+		  cosix *= exp_t;
+		}
+	      if (rx > t)
+		{
+		  /* Overflow (original real part of x > 3t).  */
+		  __real__ retval = FLT_MAX * cosix;
+		  __imag__ retval = FLT_MAX * sinix;
+		}
+	      else
+		{
+		  float exp_val = __ieee754_expf (rx);
+		  __real__ retval = exp_val * cosix;
+		  __imag__ retval = exp_val * sinix;
+		}
+	    }
+	  else
+	    {
+	      __real__ retval = __ieee754_coshf (__real__ x) * cosix;
+	      __imag__ retval = __ieee754_sinhf (__real__ x) * sinix;
+	    }
 	}
       else
 	{
diff --git a/math/s_ccoshl.c b/math/s_ccoshl.c
index 32fdd8cf81..77a9ae3869 100644
--- a/math/s_ccoshl.c
+++ b/math/s_ccoshl.c
@@ -1,5 +1,5 @@
 /* Complex cosine hyperbole function for long double.
-   Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,9 +20,8 @@
 #include <complex.h>
 #include <fenv.h>
 #include <math.h>
-
 #include <math_private.h>
-
+#include <float.h>
 
 __complex__ long double
 __ccoshl (__complex__ long double x)
@@ -37,14 +36,44 @@ __ccoshl (__complex__ long double x)
       if (__builtin_expect (icls >= FP_ZERO, 1))
 	{
 	  /* Imaginary part is finite.  */
-	  long double sinh_val = __ieee754_sinhl (__real__ x);
-	  long double cosh_val = __ieee754_coshl (__real__ x);
+	  const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
 	  long double sinix, cosix;
 
 	  __sincosl (__imag__ x, &sinix, &cosix);
 
-	  __real__ retval = cosh_val * cosix;
-	  __imag__ retval = sinh_val * sinix;
+	  if (fabsl (__real__ x) > t)
+	    {
+	      long double exp_t = __ieee754_expl (t);
+	      long double rx = fabsl (__real__ x);
+	      if (signbit (__real__ x))
+		sinix = -sinix;
+	      rx -= t;
+	      sinix *= exp_t / 2.0L;
+	      cosix *= exp_t / 2.0L;
+	      if (rx > t)
+		{
+		  rx -= t;
+		  sinix *= exp_t;
+		  cosix *= exp_t;
+		}
+	      if (rx > t)
+		{
+		  /* Overflow (original real part of x > 3t).  */
+		  __real__ retval = LDBL_MAX * cosix;
+		  __imag__ retval = LDBL_MAX * sinix;
+		}
+	      else
+		{
+		  long double exp_val = __ieee754_expl (rx);
+		  __real__ retval = exp_val * cosix;
+		  __imag__ retval = exp_val * sinix;
+		}
+	    }
+	  else
+	    {
+	      __real__ retval = __ieee754_coshl (__real__ x) * cosix;
+	      __imag__ retval = __ieee754_sinhl (__real__ x) * sinix;
+	    }
 	}
       else
 	{
diff --git a/math/s_csin.c b/math/s_csin.c
index cd4c8f0201..602c14e537 100644
--- a/math/s_csin.c
+++ b/math/s_csin.c
@@ -1,5 +1,5 @@
 /* Complex sine function for double.
-   Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,9 +20,8 @@
 #include <complex.h>
 #include <fenv.h>
 #include <math.h>
-
 #include <math_private.h>
-
+#include <float.h>
 
 __complex__ double
 __csin (__complex__ double x)
@@ -40,14 +39,44 @@ __csin (__complex__ double x)
       if (__builtin_expect (rcls >= FP_ZERO, 1))
 	{
 	  /* Real part is finite.  */
-	  double sinh_val = __ieee754_sinh (__imag__ x);
-	  double cosh_val = __ieee754_cosh (__imag__ x);
+	  const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
 	  double sinix, cosix;
 
 	  __sincos (__real__ x, &sinix, &cosix);
 
-	  __real__ retval = cosh_val * sinix;
-	  __imag__ retval = sinh_val * cosix;
+	  if (fabs (__imag__ x) > t)
+	    {
+	      double exp_t = __ieee754_exp (t);
+	      double ix = fabs (__imag__ x);
+	      if (signbit (__imag__ x))
+		cosix = -cosix;
+	      ix -= t;
+	      sinix *= exp_t / 2.0;
+	      cosix *= exp_t / 2.0;
+	      if (ix > t)
+		{
+		  ix -= t;
+		  sinix *= exp_t;
+		  cosix *= exp_t;
+		}
+	      if (ix > t)
+		{
+		  /* Overflow (original imaginary part of x > 3t).  */
+		  __real__ retval = DBL_MAX * sinix;
+		  __imag__ retval = DBL_MAX * cosix;
+		}
+	      else
+		{
+		  double exp_val = __ieee754_exp (ix);
+		  __real__ retval = exp_val * sinix;
+		  __imag__ retval = exp_val * cosix;
+		}
+	    }
+	  else
+	    {
+	      __real__ retval = __ieee754_cosh (__imag__ x) * sinix;
+	      __imag__ retval = __ieee754_sinh (__imag__ x) * cosix;
+	    }
 
 	  if (negate)
 	    __real__ retval = -__real__ retval;
diff --git a/math/s_csinf.c b/math/s_csinf.c
index d86cd3b4a1..c1d6a4f28e 100644
--- a/math/s_csinf.c
+++ b/math/s_csinf.c
@@ -1,5 +1,5 @@
 /* Complex sine function for float.
-   Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,9 +20,8 @@
 #include <complex.h>
 #include <fenv.h>
 #include <math.h>
-
 #include <math_private.h>
-
+#include <float.h>
 
 __complex__ float
 __csinf (__complex__ float x)
@@ -40,14 +39,44 @@ __csinf (__complex__ float x)
       if (__builtin_expect (rcls >= FP_ZERO, 1))
 	{
 	  /* Real part is finite.  */
-	  float sinh_val = __ieee754_sinhf (__imag__ x);
-	  float cosh_val = __ieee754_coshf (__imag__ x);
+	  const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2);
 	  float sinix, cosix;
 
 	  __sincosf (__real__ x, &sinix, &cosix);
 
-	  __real__ retval = cosh_val * sinix;
-	  __imag__ retval = sinh_val * cosix;
+	  if (fabsf (__imag__ x) > t)
+	    {
+	      float exp_t = __ieee754_expf (t);
+	      float ix = fabsf (__imag__ x);
+	      if (signbit (__imag__ x))
+		cosix = -cosix;
+	      ix -= t;
+	      sinix *= exp_t / 2.0f;
+	      cosix *= exp_t / 2.0f;
+	      if (ix > t)
+		{
+		  ix -= t;
+		  sinix *= exp_t;
+		  cosix *= exp_t;
+		}
+	      if (ix > t)
+		{
+		  /* Overflow (original imaginary part of x > 3t).  */
+		  __real__ retval = FLT_MAX * sinix;
+		  __imag__ retval = FLT_MAX * cosix;
+		}
+	      else
+		{
+		  float exp_val = __ieee754_expf (ix);
+		  __real__ retval = exp_val * sinix;
+		  __imag__ retval = exp_val * cosix;
+		}
+	    }
+	  else
+	    {
+	      __real__ retval = __ieee754_coshf (__imag__ x) * sinix;
+	      __imag__ retval = __ieee754_sinhf (__imag__ x) * cosix;
+	    }
 
 	  if (negate)
 	    __real__ retval = -__real__ retval;
diff --git a/math/s_csinh.c b/math/s_csinh.c
index f054dfc278..56bb256239 100644
--- a/math/s_csinh.c
+++ b/math/s_csinh.c
@@ -1,5 +1,5 @@
 /* Complex sine hyperbole function for double.
-   Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,9 +20,8 @@
 #include <complex.h>
 #include <fenv.h>
 #include <math.h>
-
 #include <math_private.h>
-
+#include <float.h>
 
 __complex__ double
 __csinh (__complex__ double x)
@@ -40,14 +39,44 @@ __csinh (__complex__ double x)
       if (__builtin_expect (icls >= FP_ZERO, 1))
 	{
 	  /* Imaginary part is finite.  */
-	  double sinh_val = __ieee754_sinh (__real__ x);
-	  double cosh_val = __ieee754_cosh (__real__ x);
+	  const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
 	  double sinix, cosix;
 
 	  __sincos (__imag__ x, &sinix, &cosix);
 
-	  __real__ retval = sinh_val * cosix;
-	  __imag__ retval = cosh_val * sinix;
+	  if (fabs (__real__ x) > t)
+	    {
+	      double exp_t = __ieee754_exp (t);
+	      double rx = fabs (__real__ x);
+	      if (signbit (__real__ x))
+		cosix = -cosix;
+	      rx -= t;
+	      sinix *= exp_t / 2.0;
+	      cosix *= exp_t / 2.0;
+	      if (rx > t)
+		{
+		  rx -= t;
+		  sinix *= exp_t;
+		  cosix *= exp_t;
+		}
+	      if (rx > t)
+		{
+		  /* Overflow (original real part of x > 3t).  */
+		  __real__ retval = DBL_MAX * cosix;
+		  __imag__ retval = DBL_MAX * sinix;
+		}
+	      else
+		{
+		  double exp_val = __ieee754_exp (rx);
+		  __real__ retval = exp_val * cosix;
+		  __imag__ retval = exp_val * sinix;
+		}
+	    }
+	  else
+	    {
+	      __real__ retval = __ieee754_sinh (__real__ x) * cosix;
+	      __imag__ retval = __ieee754_cosh (__real__ x) * sinix;
+	    }
 
 	  if (negate)
 	    __real__ retval = -__real__ retval;
diff --git a/math/s_csinhf.c b/math/s_csinhf.c
index 926bb37990..ba85e79b8a 100644
--- a/math/s_csinhf.c
+++ b/math/s_csinhf.c
@@ -1,5 +1,5 @@
 /* Complex sine hyperbole function for float.
-   Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,9 +20,8 @@
 #include <complex.h>
 #include <fenv.h>
 #include <math.h>
-
 #include <math_private.h>
-
+#include <float.h>
 
 __complex__ float
 __csinhf (__complex__ float x)
@@ -40,14 +39,44 @@ __csinhf (__complex__ float x)
       if (__builtin_expect (icls >= FP_ZERO, 1))
 	{
 	  /* Imaginary part is finite.  */
-	  float sinh_val = __ieee754_sinhf (__real__ x);
-	  float cosh_val = __ieee754_coshf (__real__ x);
+	  const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2);
 	  float sinix, cosix;
 
 	  __sincosf (__imag__ x, &sinix, &cosix);
 
-	  __real__ retval = sinh_val * cosix;
-	  __imag__ retval = cosh_val * sinix;
+	  if (fabsf (__real__ x) > t)
+	    {
+	      float exp_t = __ieee754_expf (t);
+	      float rx = fabsf (__real__ x);
+	      if (signbit (__real__ x))
+		cosix = -cosix;
+	      rx -= t;
+	      sinix *= exp_t / 2.0f;
+	      cosix *= exp_t / 2.0f;
+	      if (rx > t)
+		{
+		  rx -= t;
+		  sinix *= exp_t;
+		  cosix *= exp_t;
+		}
+	      if (rx > t)
+		{
+		  /* Overflow (original real part of x > 3t).  */
+		  __real__ retval = FLT_MAX * cosix;
+		  __imag__ retval = FLT_MAX * sinix;
+		}
+	      else
+		{
+		  float exp_val = __ieee754_expf (rx);
+		  __real__ retval = exp_val * cosix;
+		  __imag__ retval = exp_val * sinix;
+		}
+	    }
+	  else
+	    {
+	      __real__ retval = __ieee754_sinhf (__real__ x) * cosix;
+	      __imag__ retval = __ieee754_coshf (__real__ x) * sinix;
+	    }
 
 	  if (negate)
 	    __real__ retval = -__real__ retval;
diff --git a/math/s_csinhl.c b/math/s_csinhl.c
index ff0e8b3871..e482e3a62e 100644
--- a/math/s_csinhl.c
+++ b/math/s_csinhl.c
@@ -1,5 +1,5 @@
 /* Complex sine hyperbole function for long double.
-   Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,9 +20,8 @@
 #include <complex.h>
 #include <fenv.h>
 #include <math.h>
-
 #include <math_private.h>
-
+#include <float.h>
 
 __complex__ long double
 __csinhl (__complex__ long double x)
@@ -40,14 +39,44 @@ __csinhl (__complex__ long double x)
       if (__builtin_expect (icls >= FP_ZERO, 1))
 	{
 	  /* Imaginary part is finite.  */
-	  long double sinh_val = __ieee754_sinhl (__real__ x);
-	  long double cosh_val = __ieee754_coshl (__real__ x);
+	  const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
 	  long double sinix, cosix;
 
 	  __sincosl (__imag__ x, &sinix, &cosix);
 
-	  __real__ retval = sinh_val * cosix;
-	  __imag__ retval = cosh_val * sinix;
+	  if (fabsl (__real__ x) > t)
+	    {
+	      long double exp_t = __ieee754_expl (t);
+	      long double rx = fabsl (__real__ x);
+	      if (signbit (__real__ x))
+		cosix = -cosix;
+	      rx -= t;
+	      sinix *= exp_t / 2.0L;
+	      cosix *= exp_t / 2.0L;
+	      if (rx > t)
+		{
+		  rx -= t;
+		  sinix *= exp_t;
+		  cosix *= exp_t;
+		}
+	      if (rx > t)
+		{
+		  /* Overflow (original real part of x > 3t).  */
+		  __real__ retval = LDBL_MAX * cosix;
+		  __imag__ retval = LDBL_MAX * sinix;
+		}
+	      else
+		{
+		  long double exp_val = __ieee754_expl (rx);
+		  __real__ retval = exp_val * cosix;
+		  __imag__ retval = exp_val * sinix;
+		}
+	    }
+	  else
+	    {
+	      __real__ retval = __ieee754_sinhl (__real__ x) * cosix;
+	      __imag__ retval = __ieee754_coshl (__real__ x) * sinix;
+	    }
 
 	  if (negate)
 	    __real__ retval = -__real__ retval;
diff --git a/math/s_csinl.c b/math/s_csinl.c
index df20e8b338..ff43256e54 100644
--- a/math/s_csinl.c
+++ b/math/s_csinl.c
@@ -1,5 +1,5 @@
 /* Complex sine function for long double.
-   Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -20,9 +20,8 @@
 #include <complex.h>
 #include <fenv.h>
 #include <math.h>
-
 #include <math_private.h>
-
+#include <float.h>
 
 __complex__ long double
 __csinl (__complex__ long double x)
@@ -40,14 +39,44 @@ __csinl (__complex__ long double x)
       if (__builtin_expect (rcls >= FP_ZERO, 1))
 	{
 	  /* Real part is finite.  */
-	  long double sinh_val = __ieee754_sinhl (__imag__ x);
-	  long double cosh_val = __ieee754_coshl (__imag__ x);
+	  const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
 	  long double sinix, cosix;
 
 	  __sincosl (__real__ x, &sinix, &cosix);
 
-	  __real__ retval = cosh_val * sinix;
-	  __imag__ retval = sinh_val * cosix;
+	  if (fabsl (__imag__ x) > t)
+	    {
+	      long double exp_t = __ieee754_expl (t);
+	      long double ix = fabsl (__imag__ x);
+	      if (signbit (__imag__ x))
+		cosix = -cosix;
+	      ix -= t;
+	      sinix *= exp_t / 2.0L;
+	      cosix *= exp_t / 2.0L;
+	      if (ix > t)
+		{
+		  ix -= t;
+		  sinix *= exp_t;
+		  cosix *= exp_t;
+		}
+	      if (ix > t)
+		{
+		  /* Overflow (original imaginary part of x > 3t).  */
+		  __real__ retval = LDBL_MAX * sinix;
+		  __imag__ retval = LDBL_MAX * cosix;
+		}
+	      else
+		{
+		  long double exp_val = __ieee754_expl (ix);
+		  __real__ retval = exp_val * sinix;
+		  __imag__ retval = exp_val * cosix;
+		}
+	    }
+	  else
+	    {
+	      __real__ retval = __ieee754_coshl (__imag__ x) * sinix;
+	      __imag__ retval = __ieee754_sinhl (__imag__ x) * cosix;
+	    }
 
 	  if (negate)
 	    __real__ retval = -__real__ retval;
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index cdc26a0c63..b4ca2127d7 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -576,6 +576,33 @@ ildouble: 1
 ldouble: 1
 
 # ccos
+Test "Real part of: ccos (-0.75 + 710.5 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (-0.75 + 710.5 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: ccos (-0.75 + 89.5 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (-0.75 + 89.5 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccos (-0.75 - 710.5 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (-0.75 - 710.5 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: ccos (-0.75 - 89.5 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (-0.75 - 89.5 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+float: 1
+ifloat: 1
 Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
 float: 1
 ifloat: 1
@@ -583,12 +610,41 @@ ildouble: 1
 ldouble: 1
 Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
 double: 1
+float: 1
 idouble: 1
+ifloat: 1
 ildouble: 1
 ldouble: 1
 Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
 ildouble: 1
 ldouble: 1
+Test "Real part of: ccos (0.75 + 710.5 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (0.75 + 710.5 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: ccos (0.75 + 89.5 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 + 89.5 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccos (0.75 - 710.5 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (0.75 - 710.5 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: ccos (0.75 - 89.5 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 - 89.5 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0x1p-1074 + 1440 i) == inf - 5.981479269486130556466515778180916082415e301 i plus overflow exception":
+double: 1
+idouble: 1
 
 # ccosh
 Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
@@ -598,6 +654,30 @@ idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "Real part of: ccosh (-710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (-710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: ccosh (-710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (-710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: ccosh (-89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccosh (-89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
 Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
 double: 1
 float: 1
@@ -608,6 +688,33 @@ double: 1
 float: 1
 idouble: 1
 ifloat: 1
+Test "Imaginary part of: ccosh (1440 + 0x1p-1074 i) == inf + 5.981479269486130556466515778180916082415e301 i plus overflow exception":
+double: 1
+idouble: 1
+Test "Real part of: ccosh (710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: ccosh (710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: ccosh (89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: ccosh (89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
 
 # cexp
 Test "Real part of: cexp (-10000 + 0x1p16383 i) == 1.045876464564882298442774542991176546722e-4343 + 4.421154026488516836023811173959413420548e-4344 i":
@@ -1130,6 +1237,30 @@ ildouble: 1
 ldouble: 1
 
 # csin
+Test "Real part of: csin (-0.75 + 710.5 i) == -1.255317763348154410745082950806112487736e308 + 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csin (-0.75 + 710.5 i) == -1.255317763348154410745082950806112487736e308 + 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (-0.75 + 89.5 i) == -2.522786001038096774676288412995370563339e38 + 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csin (-0.75 + 89.5 i) == -2.522786001038096774676288412995370563339e38 + 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (-0.75 - 710.5 i) == -1.255317763348154410745082950806112487736e308 - 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csin (-0.75 - 710.5 i) == -1.255317763348154410745082950806112487736e308 - 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (-0.75 - 89.5 i) == -2.522786001038096774676288412995370563339e38 - 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csin (-0.75 - 89.5 i) == -2.522786001038096774676288412995370563339e38 - 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
 Test "Imaginary part of: csin (-2 - 3 i) == -9.15449914691142957346729954460983256 + 4.16890695996656435075481305885375484 i":
 float: 1
 ifloat: 1
@@ -1141,6 +1272,33 @@ ldouble: 1
 Test "Imaginary part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
 float: 1
 ifloat: 1
+Test "Real part of: csin (0.75 + 710.5 i) == 1.255317763348154410745082950806112487736e308 + 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csin (0.75 + 710.5 i) == 1.255317763348154410745082950806112487736e308 + 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (0.75 + 89.5 i) == 2.522786001038096774676288412995370563339e38 + 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csin (0.75 + 89.5 i) == 2.522786001038096774676288412995370563339e38 + 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (0.75 - 710.5 i) == 1.255317763348154410745082950806112487736e308 - 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csin (0.75 - 710.5 i) == 1.255317763348154410745082950806112487736e308 - 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (0.75 - 89.5 i) == 2.522786001038096774676288412995370563339e38 - 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csin (0.75 - 89.5 i) == 2.522786001038096774676288412995370563339e38 - 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (0x1p-1074 + 1440 i) == 5.981479269486130556466515778180916082415e301 + inf i plus overflow exception":
+double: 1
+idouble: 1
 
 # csinh
 Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
@@ -1153,6 +1311,30 @@ idouble: 1
 ifloat: 1
 ildouble: 2
 ldouble: 2
+Test "Real part of: csinh (-710.5 + 0.75 i) == -1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-710.5 + 0.75 i) == -1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (-710.5 - 0.75 i) == -1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-710.5 - 0.75 i) == -1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (-89.5 + 0.75 i) == -2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (-89.5 + 0.75 i) == -2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csinh (-89.5 - 0.75 i) == -2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (-89.5 - 0.75 i) == -2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
 Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
 double: 1
 float: 1
@@ -1163,6 +1345,33 @@ ldouble: 1
 Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
 float: 1
 ifloat: 1
+Test "Imaginary part of: csinh (1440 + 0x1p-1074 i) == inf + 5.981479269486130556466515778180916082415e301 i plus overflow exception":
+double: 1
+idouble: 1
+Test "Real part of: csinh (710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csinh (89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csinh (89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
 
 # csqrt
 Test "Imaginary part of: csqrt (0x1.fffffffffffffp+1023 + 0x1p+1023 i) == 1.379778091031440685006200821918878702861e+154 + 3.257214233483129514781233066898042490248e+153 i":
@@ -2474,12 +2683,16 @@ ldouble: 1
 
 Function: Real part of "ccos":
 double: 1
+float: 1
 idouble: 1
+ifloat: 1
 ildouble: 1
 ldouble: 1
 
 Function: Imaginary part of "ccos":
+double: 1
 float: 1
+idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
@@ -2616,13 +2829,17 @@ ildouble: 4
 ldouble: 4
 
 Function: Real part of "csin":
+double: 1
 float: 1
+idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
 
 Function: Imaginary part of "csin":
+double: 1
 float: 1
+idouble: 1
 ifloat: 1
 
 Function: Real part of "csinh":
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index 9bb26d1fe7..d3770c8d1d 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -576,6 +576,18 @@ ildouble: 1
 ldouble: 1
 
 # ccos
+Test "Imaginary part of: ccos (-0.75 + 710.5 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (-0.75 + 89.5 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (-0.75 - 710.5 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (-0.75 - 89.5 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
 Test "Real part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
 double: 1
 idouble: 1
@@ -596,6 +608,21 @@ float: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "Imaginary part of: ccos (0.75 + 710.5 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (0.75 + 89.5 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0.75 - 710.5 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccos (0.75 - 89.5 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccos (0x1p-1074 + 1440 i) == inf - 5.981479269486130556466515778180916082415e301 i plus overflow exception":
+double: 1
+idouble: 1
 
 # ccosh
 Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
@@ -608,6 +635,18 @@ idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "Imaginary part of: ccosh (-710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (-710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (-89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (-89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
 Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
 double: 1
 float: 1
@@ -616,6 +655,21 @@ ifloat: 1
 Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
 float: 1
 ifloat: 1
+Test "Imaginary part of: ccosh (1440 + 0x1p-1074 i) == inf + 5.981479269486130556466515778180916082415e301 i plus overflow exception":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: ccosh (89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: ccosh (89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
 
 # cexp
 Test "Real part of: cexp (-10000 + 0x1p16383 i) == 1.045876464564882298442774542991176546722e-4343 + 4.421154026488516836023811173959413420548e-4344 i":
@@ -1085,6 +1139,18 @@ ildouble: 1
 ldouble: 1
 
 # csin
+Test "Real part of: csin (-0.75 + 710.5 i) == -1.255317763348154410745082950806112487736e308 + 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (-0.75 + 89.5 i) == -2.522786001038096774676288412995370563339e38 + 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (-0.75 - 710.5 i) == -1.255317763348154410745082950806112487736e308 - 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (-0.75 - 89.5 i) == -2.522786001038096774676288412995370563339e38 - 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
 Test "Imaginary part of: csin (-2 - 3 i) == -9.15449914691142957346729954460983256 + 4.16890695996656435075481305885375484 i":
 double: 1
 idouble: 1
@@ -1094,6 +1160,21 @@ ldouble: 1
 Test "Imaginary part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
 float: 1
 ifloat: 1
+Test "Real part of: csin (0.75 + 710.5 i) == 1.255317763348154410745082950806112487736e308 + 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (0.75 + 89.5 i) == 2.522786001038096774676288412995370563339e38 + 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (0.75 - 710.5 i) == 1.255317763348154410745082950806112487736e308 - 1.347490911916428129246890157395342279438e308 i":
+double: 1
+idouble: 1
+Test "Real part of: csin (0.75 - 89.5 i) == 2.522786001038096774676288412995370563339e38 - 2.708024460708609732016532185663087200560e38 i":
+float: 1
+ifloat: 1
+Test "Real part of: csin (0x1p-1074 + 1440 i) == 5.981479269486130556466515778180916082415e301 + inf i plus overflow exception":
+double: 1
+idouble: 1
 
 # csinh
 Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
@@ -1104,6 +1185,18 @@ double: 1
 idouble: 1
 ildouble: 2
 ldouble: 2
+Test "Imaginary part of: csinh (-710.5 + 0.75 i) == -1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-710.5 - 0.75 i) == -1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (-89.5 + 0.75 i) == -2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (-89.5 - 0.75 i) == -2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
 Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
 float: 1
 ifloat: 1
@@ -1112,6 +1205,21 @@ ldouble: 1
 Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
 float: 1
 ifloat: 1
+Test "Imaginary part of: csinh (1440 + 0x1p-1074 i) == inf + 5.981479269486130556466515778180916082415e301 i plus overflow exception":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (710.5 + 0.75 i) == 1.347490911916428129246890157395342279438e308 + 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (710.5 - 0.75 i) == 1.347490911916428129246890157395342279438e308 - 1.255317763348154410745082950806112487736e308 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: csinh (89.5 + 0.75 i) == 2.708024460708609732016532185663087200560e38 + 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: csinh (89.5 - 0.75 i) == 2.708024460708609732016532185663087200560e38 - 2.522786001038096774676288412995370563339e38 i":
+float: 1
+ifloat: 1
 
 # csqrt
 Test "Real part of: csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i":
@@ -2368,7 +2476,9 @@ ildouble: 1
 ldouble: 1
 
 Function: Imaginary part of "ccos":
+double: 1
 float: 1
+idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
@@ -2500,6 +2610,10 @@ ildouble: 4
 ldouble: 4
 
 Function: Real part of "csin":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
 ildouble: 1
 ldouble: 1