about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog36
-rw-r--r--NEWS2
-rw-r--r--math/auto-libm-test-in10
-rw-r--r--math/auto-libm-test-out263
-rw-r--r--math/gen-libm-have-vector-test.sh8
-rw-r--r--math/libm-test.inc5
-rw-r--r--sysdeps/i386/fpu/libm-test-ulps36
-rw-r--r--sysdeps/ieee754/dbl-64/e_gamma_r.c87
-rw-r--r--sysdeps/ieee754/flt-32/e_gammaf_r.c88
-rw-r--r--sysdeps/ieee754/ldbl-128/e_gammal_r.c74
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c74
-rw-r--r--sysdeps/ieee754/ldbl-96/e_gammal_r.c74
-rw-r--r--sysdeps/x86_64/fpu/libm-test-ulps32
13 files changed, 540 insertions, 249 deletions
diff --git a/ChangeLog b/ChangeLog
index 9f91f183b5..41176b5fc8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,41 @@
 2015-06-29  Joseph Myers  <joseph@codesourcery.com>
 
+	[BZ #18613]
+	* sysdeps/ieee754/dbl-64/e_gamma_r.c (gamma_positive): Take log of
+	X_ADJ not X when adjusting exponent.
+	(__ieee754_gamma_r): Do intermediate computations in
+	round-to-nearest then adjust overflowing and underflowing results
+	as needed.
+	* sysdeps/ieee754/flt-32/e_gammaf_r.c (gammaf_positive): Take log
+	of X_ADJ not X when adjusting exponent.
+	(__ieee754_gammaf_r): Do intermediate computations in
+	round-to-nearest then adjust overflowing and underflowing results
+	as needed.
+	* sysdeps/ieee754/ldbl-128/e_gammal_r.c (gammal_positive): Take
+	log of X_ADJ not X when adjusting exponent.
+	(__ieee754_gammal_r): Do intermediate computations in
+	round-to-nearest then adjust overflowing and underflowing results
+	as needed.  Use 1.0L not 1.0f as numerator of division.
+	* sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c (gammal_positive): Take
+	log of X_ADJ not X when adjusting exponent.
+	(__ieee754_gammal_r): Do intermediate computations in
+	round-to-nearest then adjust overflowing and underflowing results
+	as needed.  Use 1.0L not 1.0f as numerator of division.
+	* sysdeps/ieee754/ldbl-96/e_gammal_r.c (gammal_positive): Take log
+	of X_ADJ not X when adjusting exponent.
+	(__ieee754_gammal_r): Do intermediate computations in
+	round-to-nearest then adjust overflowing and underflowing results
+	as needed.  Use 1.0L not 1.0f as numerator of division.
+	* math/libm-test.inc (tgamma_test_data): Remove one test.  Moved
+	to auto-libm-test-in.
+	(tgamma_test): Use ALL_RM_TEST.
+	* math/auto-libm-test-in: Add one test of tgamma.  Mark some other
+	tests of tgamma with spurious-overflow.
+	* math/auto-libm-test-out: Regenerated.
+	* math/gen-libm-have-vector-test.sh: Do not check for START.
+	* sysdeps/i386/fpu/libm-test-ulps: Update.
+	* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
 	[BZ #18612]
 	* sysdeps/ieee754/ldbl-128/e_j1l.c (__ieee754_j1l): For small
 	arguments, just return 0.5 times the argument, with underflow
diff --git a/NEWS b/NEWS
index 08899a8162..69d9f73932 100644
--- a/NEWS
+++ b/NEWS
@@ -25,7 +25,7 @@ Version 2.22
   18497, 18498, 18502, 18507, 18512, 18513, 18519, 18520, 18522, 18527,
   18528, 18529, 18530, 18532, 18533, 18534, 18536, 18539, 18540, 18542,
   18544, 18545, 18546, 18547, 18549, 18553, 18558, 18569, 18583, 18585,
-  18586, 18593, 18594, 18602, 18612.
+  18586, 18593, 18594, 18602, 18612, 18613.
 
 * Cache information can be queried via sysconf() function on s390 e.g. with
   _SC_LEVEL1_ICACHE_SIZE as argument.
diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in
index f4313a2b99..f783c5b2e8 100644
--- a/math/auto-libm-test-in
+++ b/math/auto-libm-test-in
@@ -2682,19 +2682,22 @@ tgamma 0x1p-113
 tgamma -0x1p-113
 tgamma 0x1p-127
 tgamma -0x1p-127
-tgamma 0x1p-128
+# IEEE semantics mean overflow very close to the threshold depends on
+# the rounding mode; gen-auto-libm-tests does not reflect that glibc
+# does not try to achieve this.
+tgamma 0x1p-128 spurious-overflow:flt-32
 tgamma -0x1p-128
 tgamma 0x1p-149
 tgamma -0x1p-149
 tgamma 0x1p-1023
 tgamma -0x1p-1023
-tgamma 0x1p-1024
+tgamma 0x1p-1024 spurious-overflow:dbl-64 spurious-overflow:ldbl-128ibm
 tgamma -0x1p-1024
 tgamma 0x1p-1074
 tgamma -0x1p-1074
 tgamma 0x1p-16383
 tgamma -0x1p-16383
-tgamma 0x1p-16384
+tgamma 0x1p-16384 spurious-overflow:ldbl-96-intel spurious-overflow:ldbl-96-m68k spurious-overflow:ldbl-128
 tgamma -0x1p-16384
 tgamma 0x1p-16445
 tgamma -0x1p-16445
@@ -3075,6 +3078,7 @@ tgamma 0x6.db8c603359a971081bc4a2e9dfdp+8
 tgamma 0x6.db8c603359a971081bc4a2e9dfd4p+8
 tgamma 1e3
 tgamma -100000.5
+tgamma max
 
 tgamma -0x3.06644cp+0
 tgamma -0x6.fe4636e0c5064p+0
diff --git a/math/auto-libm-test-out b/math/auto-libm-test-out
index b71429b4ac..14fbd03c94 100644
--- a/math/auto-libm-test-out
+++ b/math/auto-libm-test-out
@@ -197134,31 +197134,31 @@ tgamma -0x1p-127
 = tgamma tonearest ldbl-128ibm -0x2p-128L : -0x8p+124L : inexact-ok
 = tgamma towardzero ldbl-128ibm -0x2p-128L : -0x8p+124L : inexact-ok
 = tgamma upward ldbl-128ibm -0x2p-128L : -0x8p+124L : inexact-ok
-tgamma 0x1p-128
-= tgamma downward flt-32 0x1p-128f : 0xf.fffffp+124f : inexact-ok
+tgamma 0x1p-128 spurious-overflow:flt-32
+= tgamma downward flt-32 0x1p-128f : 0xf.fffffp+124f : inexact-ok overflow-ok:flt-32
 = tgamma tonearest flt-32 0x1p-128f : plus_infty : inexact-ok overflow errno-erange
-= tgamma towardzero flt-32 0x1p-128f : 0xf.fffffp+124f : inexact-ok
+= tgamma towardzero flt-32 0x1p-128f : 0xf.fffffp+124f : inexact-ok overflow-ok:flt-32
 = tgamma upward flt-32 0x1p-128f : plus_infty : inexact-ok overflow errno-erange
-= tgamma downward dbl-64 0x1p-128 : 0xf.ffffffffffff8p+124 : inexact-ok
-= tgamma tonearest dbl-64 0x1p-128 : 0x1p+128 : inexact-ok
-= tgamma towardzero dbl-64 0x1p-128 : 0xf.ffffffffffff8p+124 : inexact-ok
-= tgamma upward dbl-64 0x1p-128 : 0x1p+128 : inexact-ok
-= tgamma downward ldbl-96-intel 0x1p-128L : 0xf.fffffffffffffffp+124L : inexact-ok
-= tgamma tonearest ldbl-96-intel 0x1p-128L : 0x1p+128L : inexact-ok
-= tgamma towardzero ldbl-96-intel 0x1p-128L : 0xf.fffffffffffffffp+124L : inexact-ok
-= tgamma upward ldbl-96-intel 0x1p-128L : 0x1p+128L : inexact-ok
-= tgamma downward ldbl-96-m68k 0x1p-128L : 0xf.fffffffffffffffp+124L : inexact-ok
-= tgamma tonearest ldbl-96-m68k 0x1p-128L : 0x1p+128L : inexact-ok
-= tgamma towardzero ldbl-96-m68k 0x1p-128L : 0xf.fffffffffffffffp+124L : inexact-ok
-= tgamma upward ldbl-96-m68k 0x1p-128L : 0x1p+128L : inexact-ok
-= tgamma downward ldbl-128 0x1p-128L : 0xf.fffffffffffffffffffffffffff8p+124L : inexact-ok
-= tgamma tonearest ldbl-128 0x1p-128L : 0x1p+128L : inexact-ok
-= tgamma towardzero ldbl-128 0x1p-128L : 0xf.fffffffffffffffffffffffffff8p+124L : inexact-ok
-= tgamma upward ldbl-128 0x1p-128L : 0x1p+128L : inexact-ok
-= tgamma downward ldbl-128ibm 0x1p-128L : 0xf.fffffffffffffffffffffffffcp+124L : inexact-ok
-= tgamma tonearest ldbl-128ibm 0x1p-128L : 0x1p+128L : inexact-ok
-= tgamma towardzero ldbl-128ibm 0x1p-128L : 0xf.fffffffffffffffffffffffffcp+124L : inexact-ok
-= tgamma upward ldbl-128ibm 0x1p-128L : 0x1p+128L : inexact-ok
+= tgamma downward dbl-64 0x1p-128 : 0xf.ffffffffffff8p+124 : inexact-ok overflow-ok:flt-32
+= tgamma tonearest dbl-64 0x1p-128 : 0x1p+128 : inexact-ok overflow-ok:flt-32
+= tgamma towardzero dbl-64 0x1p-128 : 0xf.ffffffffffff8p+124 : inexact-ok overflow-ok:flt-32
+= tgamma upward dbl-64 0x1p-128 : 0x1p+128 : inexact-ok overflow-ok:flt-32
+= tgamma downward ldbl-96-intel 0x1p-128L : 0xf.fffffffffffffffp+124L : inexact-ok overflow-ok:flt-32
+= tgamma tonearest ldbl-96-intel 0x1p-128L : 0x1p+128L : inexact-ok overflow-ok:flt-32
+= tgamma towardzero ldbl-96-intel 0x1p-128L : 0xf.fffffffffffffffp+124L : inexact-ok overflow-ok:flt-32
+= tgamma upward ldbl-96-intel 0x1p-128L : 0x1p+128L : inexact-ok overflow-ok:flt-32
+= tgamma downward ldbl-96-m68k 0x1p-128L : 0xf.fffffffffffffffp+124L : inexact-ok overflow-ok:flt-32
+= tgamma tonearest ldbl-96-m68k 0x1p-128L : 0x1p+128L : inexact-ok overflow-ok:flt-32
+= tgamma towardzero ldbl-96-m68k 0x1p-128L : 0xf.fffffffffffffffp+124L : inexact-ok overflow-ok:flt-32
+= tgamma upward ldbl-96-m68k 0x1p-128L : 0x1p+128L : inexact-ok overflow-ok:flt-32
+= tgamma downward ldbl-128 0x1p-128L : 0xf.fffffffffffffffffffffffffff8p+124L : inexact-ok overflow-ok:flt-32
+= tgamma tonearest ldbl-128 0x1p-128L : 0x1p+128L : inexact-ok overflow-ok:flt-32
+= tgamma towardzero ldbl-128 0x1p-128L : 0xf.fffffffffffffffffffffffffff8p+124L : inexact-ok overflow-ok:flt-32
+= tgamma upward ldbl-128 0x1p-128L : 0x1p+128L : inexact-ok overflow-ok:flt-32
+= tgamma downward ldbl-128ibm 0x1p-128L : 0xf.fffffffffffffffffffffffffcp+124L : inexact-ok overflow-ok:flt-32
+= tgamma tonearest ldbl-128ibm 0x1p-128L : 0x1p+128L : inexact-ok overflow-ok:flt-32
+= tgamma towardzero ldbl-128ibm 0x1p-128L : 0xf.fffffffffffffffffffffffffcp+124L : inexact-ok overflow-ok:flt-32
+= tgamma upward ldbl-128ibm 0x1p-128L : 0x1p+128L : inexact-ok overflow-ok:flt-32
 tgamma -0x1p-128
 = tgamma downward flt-32 -0x1p-128f : minus_infty : inexact-ok overflow errno-erange
 = tgamma tonearest flt-32 -0x1p-128f : minus_infty : inexact-ok overflow errno-erange
@@ -197324,47 +197324,47 @@ tgamma -0x1p-1023
 = tgamma tonearest ldbl-128ibm -0x2p-1024L : -0x8p+1020L : inexact-ok
 = tgamma towardzero ldbl-128ibm -0x2p-1024L : -0x8p+1020L : inexact-ok
 = tgamma upward ldbl-128ibm -0x2p-1024L : -0x8p+1020L : inexact-ok
-tgamma 0x1p-1024
+tgamma 0x1p-1024 spurious-overflow:dbl-64 spurious-overflow:ldbl-128ibm
 = tgamma downward flt-32 0x8p-152f : 0xf.fffffp+124f : inexact-ok overflow errno-erange-ok
 = tgamma tonearest flt-32 0x8p-152f : plus_infty : inexact-ok overflow errno-erange
 = tgamma towardzero flt-32 0x8p-152f : 0xf.fffffp+124f : inexact-ok overflow errno-erange-ok
 = tgamma upward flt-32 0x8p-152f : plus_infty : inexact-ok overflow errno-erange
-= tgamma downward dbl-64 0x8p-152 : 0x1.fffffffffffffp+148 : inexact-ok
-= tgamma tonearest dbl-64 0x8p-152 : 0x2p+148 : inexact-ok
-= tgamma towardzero dbl-64 0x8p-152 : 0x1.fffffffffffffp+148 : inexact-ok
-= tgamma upward dbl-64 0x8p-152 : 0x2p+148 : inexact-ok
-= tgamma downward ldbl-96-intel 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok
-= tgamma tonearest ldbl-96-intel 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma towardzero ldbl-96-intel 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok
-= tgamma upward ldbl-96-intel 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma downward ldbl-96-m68k 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok
-= tgamma tonearest ldbl-96-m68k 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma towardzero ldbl-96-m68k 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok
-= tgamma upward ldbl-96-m68k 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma downward ldbl-128 0x8p-152L : 0x1.ffffffffffffffffffffffffffffp+148L : inexact-ok
-= tgamma tonearest ldbl-128 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma towardzero ldbl-128 0x8p-152L : 0x1.ffffffffffffffffffffffffffffp+148L : inexact-ok
-= tgamma upward ldbl-128 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma downward ldbl-128ibm 0x8p-152L : 0x1.ffffffffffffffffffffffffff8p+148L : inexact-ok
-= tgamma tonearest ldbl-128ibm 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma towardzero ldbl-128ibm 0x8p-152L : 0x1.ffffffffffffffffffffffffff8p+148L : inexact-ok
-= tgamma upward ldbl-128ibm 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma downward dbl-64 0x1p-1024 : 0xf.ffffffffffff8p+1020 : inexact-ok
+= tgamma downward dbl-64 0x8p-152 : 0x1.fffffffffffffp+148 : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma tonearest dbl-64 0x8p-152 : 0x2p+148 : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma towardzero dbl-64 0x8p-152 : 0x1.fffffffffffffp+148 : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma upward dbl-64 0x8p-152 : 0x2p+148 : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma downward ldbl-96-intel 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma tonearest ldbl-96-intel 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma towardzero ldbl-96-intel 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma upward ldbl-96-intel 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma downward ldbl-96-m68k 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma tonearest ldbl-96-m68k 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma towardzero ldbl-96-m68k 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma upward ldbl-96-m68k 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma downward ldbl-128 0x8p-152L : 0x1.ffffffffffffffffffffffffffffp+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma tonearest ldbl-128 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma towardzero ldbl-128 0x8p-152L : 0x1.ffffffffffffffffffffffffffffp+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma upward ldbl-128 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma downward ldbl-128ibm 0x8p-152L : 0x1.ffffffffffffffffffffffffff8p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma tonearest ldbl-128ibm 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma towardzero ldbl-128ibm 0x8p-152L : 0x1.ffffffffffffffffffffffffff8p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma upward ldbl-128ibm 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma downward dbl-64 0x1p-1024 : 0xf.ffffffffffff8p+1020 : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
 = tgamma tonearest dbl-64 0x1p-1024 : plus_infty : inexact-ok overflow errno-erange
-= tgamma towardzero dbl-64 0x1p-1024 : 0xf.ffffffffffff8p+1020 : inexact-ok
+= tgamma towardzero dbl-64 0x1p-1024 : 0xf.ffffffffffff8p+1020 : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
 = tgamma upward dbl-64 0x1p-1024 : plus_infty : inexact-ok overflow errno-erange
-= tgamma downward ldbl-96-intel 0x1p-1024L : 0xf.fffffffffffffffp+1020L : inexact-ok
-= tgamma tonearest ldbl-96-intel 0x1p-1024L : 0x1p+1024L : inexact-ok
-= tgamma towardzero ldbl-96-intel 0x1p-1024L : 0xf.fffffffffffffffp+1020L : inexact-ok
-= tgamma upward ldbl-96-intel 0x1p-1024L : 0x1p+1024L : inexact-ok
-= tgamma downward ldbl-96-m68k 0x1p-1024L : 0xf.fffffffffffffffp+1020L : inexact-ok
-= tgamma tonearest ldbl-96-m68k 0x1p-1024L : 0x1p+1024L : inexact-ok
-= tgamma towardzero ldbl-96-m68k 0x1p-1024L : 0xf.fffffffffffffffp+1020L : inexact-ok
-= tgamma upward ldbl-96-m68k 0x1p-1024L : 0x1p+1024L : inexact-ok
-= tgamma downward ldbl-128 0x1p-1024L : 0xf.fffffffffffffffffffffffffff8p+1020L : inexact-ok
-= tgamma tonearest ldbl-128 0x1p-1024L : 0x1p+1024L : inexact-ok
-= tgamma towardzero ldbl-128 0x1p-1024L : 0xf.fffffffffffffffffffffffffff8p+1020L : inexact-ok
-= tgamma upward ldbl-128 0x1p-1024L : 0x1p+1024L : inexact-ok
+= tgamma downward ldbl-96-intel 0x1p-1024L : 0xf.fffffffffffffffp+1020L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma tonearest ldbl-96-intel 0x1p-1024L : 0x1p+1024L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma towardzero ldbl-96-intel 0x1p-1024L : 0xf.fffffffffffffffp+1020L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma upward ldbl-96-intel 0x1p-1024L : 0x1p+1024L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma downward ldbl-96-m68k 0x1p-1024L : 0xf.fffffffffffffffp+1020L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma tonearest ldbl-96-m68k 0x1p-1024L : 0x1p+1024L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma towardzero ldbl-96-m68k 0x1p-1024L : 0xf.fffffffffffffffp+1020L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma upward ldbl-96-m68k 0x1p-1024L : 0x1p+1024L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma downward ldbl-128 0x1p-1024L : 0xf.fffffffffffffffffffffffffff8p+1020L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma tonearest ldbl-128 0x1p-1024L : 0x1p+1024L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma towardzero ldbl-128 0x1p-1024L : 0xf.fffffffffffffffffffffffffff8p+1020L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
+= tgamma upward ldbl-128 0x1p-1024L : 0x1p+1024L : inexact-ok overflow-ok:dbl-64 overflow-ok:ldbl-128ibm
 = tgamma downward ldbl-128ibm 0x1p-1024L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
 = tgamma tonearest ldbl-128ibm 0x1p-1024L : plus_infty : inexact-ok overflow errno-erange
 = tgamma towardzero ldbl-128ibm 0x1p-1024L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
@@ -197618,62 +197618,62 @@ tgamma -0x1p-16383
 = tgamma tonearest ldbl-128 -0x2p-16384L : -0x8p+16380L : inexact-ok
 = tgamma towardzero ldbl-128 -0x2p-16384L : -0x8p+16380L : inexact-ok
 = tgamma upward ldbl-128 -0x2p-16384L : -0x8p+16380L : inexact-ok
-tgamma 0x1p-16384
+tgamma 0x1p-16384 spurious-overflow:ldbl-96-intel spurious-overflow:ldbl-96-m68k spurious-overflow:ldbl-128
 = tgamma downward flt-32 0x8p-152f : 0xf.fffffp+124f : inexact-ok overflow errno-erange-ok
 = tgamma tonearest flt-32 0x8p-152f : plus_infty : inexact-ok overflow errno-erange
 = tgamma towardzero flt-32 0x8p-152f : 0xf.fffffp+124f : inexact-ok overflow errno-erange-ok
 = tgamma upward flt-32 0x8p-152f : plus_infty : inexact-ok overflow errno-erange
-= tgamma downward dbl-64 0x8p-152 : 0x1.fffffffffffffp+148 : inexact-ok
-= tgamma tonearest dbl-64 0x8p-152 : 0x2p+148 : inexact-ok
-= tgamma towardzero dbl-64 0x8p-152 : 0x1.fffffffffffffp+148 : inexact-ok
-= tgamma upward dbl-64 0x8p-152 : 0x2p+148 : inexact-ok
-= tgamma downward ldbl-96-intel 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok
-= tgamma tonearest ldbl-96-intel 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma towardzero ldbl-96-intel 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok
-= tgamma upward ldbl-96-intel 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma downward ldbl-96-m68k 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok
-= tgamma tonearest ldbl-96-m68k 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma towardzero ldbl-96-m68k 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok
-= tgamma upward ldbl-96-m68k 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma downward ldbl-128 0x8p-152L : 0x1.ffffffffffffffffffffffffffffp+148L : inexact-ok
-= tgamma tonearest ldbl-128 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma towardzero ldbl-128 0x8p-152L : 0x1.ffffffffffffffffffffffffffffp+148L : inexact-ok
-= tgamma upward ldbl-128 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma downward ldbl-128ibm 0x8p-152L : 0x1.ffffffffffffffffffffffffff8p+148L : inexact-ok
-= tgamma tonearest ldbl-128ibm 0x8p-152L : 0x2p+148L : inexact-ok
-= tgamma towardzero ldbl-128ibm 0x8p-152L : 0x1.ffffffffffffffffffffffffff8p+148L : inexact-ok
-= tgamma upward ldbl-128ibm 0x8p-152L : 0x2p+148L : inexact-ok
+= tgamma downward dbl-64 0x8p-152 : 0x1.fffffffffffffp+148 : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma tonearest dbl-64 0x8p-152 : 0x2p+148 : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma towardzero dbl-64 0x8p-152 : 0x1.fffffffffffffp+148 : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma upward dbl-64 0x8p-152 : 0x2p+148 : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma downward ldbl-96-intel 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma tonearest ldbl-96-intel 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma towardzero ldbl-96-intel 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma upward ldbl-96-intel 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma downward ldbl-96-m68k 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma tonearest ldbl-96-m68k 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma towardzero ldbl-96-m68k 0x8p-152L : 0x1.fffffffffffffffep+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma upward ldbl-96-m68k 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma downward ldbl-128 0x8p-152L : 0x1.ffffffffffffffffffffffffffffp+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma tonearest ldbl-128 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma towardzero ldbl-128 0x8p-152L : 0x1.ffffffffffffffffffffffffffffp+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma upward ldbl-128 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma downward ldbl-128ibm 0x8p-152L : 0x1.ffffffffffffffffffffffffff8p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma tonearest ldbl-128ibm 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma towardzero ldbl-128ibm 0x8p-152L : 0x1.ffffffffffffffffffffffffff8p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma upward ldbl-128ibm 0x8p-152L : 0x2p+148L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
 = tgamma downward dbl-64 0x4p-1076 : 0xf.ffffffffffff8p+1020 : inexact-ok overflow errno-erange-ok
 = tgamma tonearest dbl-64 0x4p-1076 : plus_infty : inexact-ok overflow errno-erange
 = tgamma towardzero dbl-64 0x4p-1076 : 0xf.ffffffffffff8p+1020 : inexact-ok overflow errno-erange-ok
 = tgamma upward dbl-64 0x4p-1076 : plus_infty : inexact-ok overflow errno-erange
-= tgamma downward ldbl-96-intel 0x4p-1076L : 0x3.fffffffffffffffcp+1072L : inexact-ok
-= tgamma tonearest ldbl-96-intel 0x4p-1076L : 0x4p+1072L : inexact-ok
-= tgamma towardzero ldbl-96-intel 0x4p-1076L : 0x3.fffffffffffffffcp+1072L : inexact-ok
-= tgamma upward ldbl-96-intel 0x4p-1076L : 0x4p+1072L : inexact-ok
-= tgamma downward ldbl-96-m68k 0x4p-1076L : 0x3.fffffffffffffffcp+1072L : inexact-ok
-= tgamma tonearest ldbl-96-m68k 0x4p-1076L : 0x4p+1072L : inexact-ok
-= tgamma towardzero ldbl-96-m68k 0x4p-1076L : 0x3.fffffffffffffffcp+1072L : inexact-ok
-= tgamma upward ldbl-96-m68k 0x4p-1076L : 0x4p+1072L : inexact-ok
-= tgamma downward ldbl-128 0x4p-1076L : 0x3.fffffffffffffffffffffffffffep+1072L : inexact-ok
-= tgamma tonearest ldbl-128 0x4p-1076L : 0x4p+1072L : inexact-ok
-= tgamma towardzero ldbl-128 0x4p-1076L : 0x3.fffffffffffffffffffffffffffep+1072L : inexact-ok
-= tgamma upward ldbl-128 0x4p-1076L : 0x4p+1072L : inexact-ok
+= tgamma downward ldbl-96-intel 0x4p-1076L : 0x3.fffffffffffffffcp+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma tonearest ldbl-96-intel 0x4p-1076L : 0x4p+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma towardzero ldbl-96-intel 0x4p-1076L : 0x3.fffffffffffffffcp+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma upward ldbl-96-intel 0x4p-1076L : 0x4p+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma downward ldbl-96-m68k 0x4p-1076L : 0x3.fffffffffffffffcp+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma tonearest ldbl-96-m68k 0x4p-1076L : 0x4p+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma towardzero ldbl-96-m68k 0x4p-1076L : 0x3.fffffffffffffffcp+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma upward ldbl-96-m68k 0x4p-1076L : 0x4p+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma downward ldbl-128 0x4p-1076L : 0x3.fffffffffffffffffffffffffffep+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma tonearest ldbl-128 0x4p-1076L : 0x4p+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma towardzero ldbl-128 0x4p-1076L : 0x3.fffffffffffffffffffffffffffep+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
+= tgamma upward ldbl-128 0x4p-1076L : 0x4p+1072L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
 = tgamma downward ldbl-128ibm 0x4p-1076L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
 = tgamma tonearest ldbl-128ibm 0x4p-1076L : plus_infty : inexact-ok overflow errno-erange
 = tgamma towardzero ldbl-128ibm 0x4p-1076L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
 = tgamma upward ldbl-128ibm 0x4p-1076L : plus_infty : inexact-ok overflow errno-erange
-= tgamma downward ldbl-96-intel 0x1p-16384L : 0xf.fffffffffffffffp+16380L : inexact-ok
+= tgamma downward ldbl-96-intel 0x1p-16384L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
 = tgamma tonearest ldbl-96-intel 0x1p-16384L : plus_infty : inexact-ok overflow errno-erange
-= tgamma towardzero ldbl-96-intel 0x1p-16384L : 0xf.fffffffffffffffp+16380L : inexact-ok
+= tgamma towardzero ldbl-96-intel 0x1p-16384L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
 = tgamma upward ldbl-96-intel 0x1p-16384L : plus_infty : inexact-ok overflow errno-erange
-= tgamma downward ldbl-96-m68k 0x1p-16384L : 0xf.fffffffffffffffp+16380L : inexact-ok
+= tgamma downward ldbl-96-m68k 0x1p-16384L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
 = tgamma tonearest ldbl-96-m68k 0x1p-16384L : plus_infty : inexact-ok overflow errno-erange
-= tgamma towardzero ldbl-96-m68k 0x1p-16384L : 0xf.fffffffffffffffp+16380L : inexact-ok
+= tgamma towardzero ldbl-96-m68k 0x1p-16384L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
 = tgamma upward ldbl-96-m68k 0x1p-16384L : plus_infty : inexact-ok overflow errno-erange
-= tgamma downward ldbl-128 0x1p-16384L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok
+= tgamma downward ldbl-128 0x1p-16384L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
 = tgamma tonearest ldbl-128 0x1p-16384L : plus_infty : inexact-ok overflow errno-erange
-= tgamma towardzero ldbl-128 0x1p-16384L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok
+= tgamma towardzero ldbl-128 0x1p-16384L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow-ok:ldbl-96-intel overflow-ok:ldbl-96-m68k overflow-ok:ldbl-128
 = tgamma upward ldbl-128 0x1p-16384L : plus_infty : inexact-ok overflow errno-erange
 tgamma -0x1p-16384
 = tgamma downward flt-32 -0x8p-152f : minus_infty : inexact-ok overflow errno-erange
@@ -221443,6 +221443,75 @@ tgamma -100000.5
 = tgamma tonearest ldbl-128ibm -0x1.86a08p+16L : -0x0p+0L : inexact-ok underflow errno-erange
 = tgamma towardzero ldbl-128ibm -0x1.86a08p+16L : -0x0p+0L : inexact-ok underflow errno-erange
 = tgamma upward ldbl-128ibm -0x1.86a08p+16L : -0x0p+0L : inexact-ok underflow errno-erange
+tgamma max
+= tgamma downward flt-32 0xf.fffffp+124f : 0xf.fffffp+124f : inexact-ok overflow errno-erange-ok
+= tgamma tonearest flt-32 0xf.fffffp+124f : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero flt-32 0xf.fffffp+124f : 0xf.fffffp+124f : inexact-ok overflow errno-erange-ok
+= tgamma upward flt-32 0xf.fffffp+124f : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward dbl-64 0xf.fffffp+124 : 0xf.ffffffffffff8p+1020 : inexact-ok overflow errno-erange-ok
+= tgamma tonearest dbl-64 0xf.fffffp+124 : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero dbl-64 0xf.fffffp+124 : 0xf.ffffffffffff8p+1020 : inexact-ok overflow errno-erange-ok
+= tgamma upward dbl-64 0xf.fffffp+124 : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-96-intel 0xf.fffffp+124L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-96-intel 0xf.fffffp+124L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-96-intel 0xf.fffffp+124L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-96-intel 0xf.fffffp+124L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-96-m68k 0xf.fffffp+124L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-96-m68k 0xf.fffffp+124L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-96-m68k 0xf.fffffp+124L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-96-m68k 0xf.fffffp+124L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-128 0xf.fffffp+124L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-128 0xf.fffffp+124L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-128 0xf.fffffp+124L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-128 0xf.fffffp+124L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-128ibm 0xf.fffffp+124L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-128ibm 0xf.fffffp+124L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-128ibm 0xf.fffffp+124L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-128ibm 0xf.fffffp+124L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward dbl-64 0xf.ffffffffffff8p+1020 : 0xf.ffffffffffff8p+1020 : inexact-ok overflow errno-erange-ok
+= tgamma tonearest dbl-64 0xf.ffffffffffff8p+1020 : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero dbl-64 0xf.ffffffffffff8p+1020 : 0xf.ffffffffffff8p+1020 : inexact-ok overflow errno-erange-ok
+= tgamma upward dbl-64 0xf.ffffffffffff8p+1020 : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-96-intel 0xf.ffffffffffff8p+1020L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-96-intel 0xf.ffffffffffff8p+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-96-intel 0xf.ffffffffffff8p+1020L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-96-intel 0xf.ffffffffffff8p+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-96-m68k 0xf.ffffffffffff8p+1020L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-96-m68k 0xf.ffffffffffff8p+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-96-m68k 0xf.ffffffffffff8p+1020L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-96-m68k 0xf.ffffffffffff8p+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-128 0xf.ffffffffffff8p+1020L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-128 0xf.ffffffffffff8p+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-128 0xf.ffffffffffff8p+1020L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-128 0xf.ffffffffffff8p+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-128ibm 0xf.ffffffffffff8p+1020L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-128ibm 0xf.ffffffffffff8p+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-128ibm 0xf.ffffffffffff8p+1020L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-128ibm 0xf.ffffffffffff8p+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-96-intel 0xf.fffffffffffffffp+16380L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-96-intel 0xf.fffffffffffffffp+16380L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-96-intel 0xf.fffffffffffffffp+16380L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-96-intel 0xf.fffffffffffffffp+16380L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-96-m68k 0xf.fffffffffffffffp+16380L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-96-m68k 0xf.fffffffffffffffp+16380L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-96-m68k 0xf.fffffffffffffffp+16380L : 0xf.fffffffffffffffp+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-96-m68k 0xf.fffffffffffffffp+16380L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-128 0xf.fffffffffffffffp+16380L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-128 0xf.fffffffffffffffp+16380L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-128 0xf.fffffffffffffffp+16380L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-128 0xf.fffffffffffffffp+16380L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-128 0xf.fffffffffffffffffffffffffff8p+16380L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-128 0xf.fffffffffffffffffffffffffff8p+16380L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-128 0xf.fffffffffffffffffffffffffff8p+16380L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-128 0xf.fffffffffffffffffffffffffff8p+16380L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-128 0xf.ffffffffffffbffffffffffffcp+1020L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-128 0xf.ffffffffffffbffffffffffffcp+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-128 0xf.ffffffffffffbffffffffffffcp+1020L : 0xf.fffffffffffffffffffffffffff8p+16380L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-128 0xf.ffffffffffffbffffffffffffcp+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma downward ldbl-128ibm 0xf.ffffffffffffbffffffffffffcp+1020L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
+= tgamma tonearest ldbl-128ibm 0xf.ffffffffffffbffffffffffffcp+1020L : plus_infty : inexact-ok overflow errno-erange
+= tgamma towardzero ldbl-128ibm 0xf.ffffffffffffbffffffffffffcp+1020L : 0xf.ffffffffffffbffffffffffffcp+1020L : inexact-ok overflow errno-erange-ok
+= tgamma upward ldbl-128ibm 0xf.ffffffffffffbffffffffffffcp+1020L : plus_infty : inexact-ok overflow errno-erange
 tgamma -0x3.06644cp+0
 = tgamma downward flt-32 -0x3.06644cp+0f : 0x6.79a69p+0f : inexact-ok
 = tgamma tonearest flt-32 -0x3.06644cp+0f : 0x6.79a698p+0f : inexact-ok
diff --git a/math/gen-libm-have-vector-test.sh b/math/gen-libm-have-vector-test.sh
index 529ea0c1ac..6532deb249 100644
--- a/math/gen-libm-have-vector-test.sh
+++ b/math/gen-libm-have-vector-test.sh
@@ -50,11 +50,3 @@ for func in $(cat libm-test.inc | grep ALL_RM_TEST | grep RUN_TEST_LOOP_fFF_11 |
   print_defs ${func}f "_fFF"
   print_defs ${func}l "_fFF"
 done
-
-# When all functions will use ALL_RM_TEST instead of using START directly,
-# this code can be removed.
-for func in $(grep 'START.*;$' libm-test.inc | sed -r "s/.*\(//; s/,.*//"); do
-  print_defs ${func}
-  print_defs ${func}f
-  print_defs ${func}l
-done
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 9e402ab634..17a20c45ad 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -9484,7 +9484,6 @@ tanh_test (void)
 static const struct test_f_f_data tgamma_test_data[] =
   {
     TEST_f_f (tgamma, plus_infty, plus_infty),
-    TEST_f_f (tgamma, max_value, plus_infty, OVERFLOW_EXCEPTION|ERRNO_ERANGE),
     TEST_f_f (tgamma, 0, plus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
     TEST_f_f (tgamma, minus_zero, minus_infty, DIVIDE_BY_ZERO_EXCEPTION|ERRNO_ERANGE),
     /* tgamma (x) == qNaN plus invalid exception for integer x <= 0.  */
@@ -9499,9 +9498,7 @@ static const struct test_f_f_data tgamma_test_data[] =
 static void
 tgamma_test (void)
 {
-  START (tgamma,, 0);
-  RUN_TEST_LOOP_f_f (tgamma, tgamma_test_data, );
-  END;
+  ALL_RM_TEST (tgamma, 0, tgamma_test_data, RUN_TEST_LOOP_f_f, END);
 }
 
 
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index 5a2af000fc..003be8e569 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -1932,12 +1932,36 @@ ildouble: 5
 ldouble: 4
 
 Function: "tgamma":
-double: 6
-float: 4
-idouble: 6
-ifloat: 4
-ildouble: 6
-ldouble: 6
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: "tgamma_downward":
+double: 2
+float: 3
+idouble: 2
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: "tgamma_towardzero":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 3
+ldouble: 3
+
+Function: "tgamma_upward":
+double: 3
+float: 3
+idouble: 3
+ifloat: 3
+ildouble: 3
+ldouble: 3
 
 Function: "y0":
 double: 1
diff --git a/sysdeps/ieee754/dbl-64/e_gamma_r.c b/sysdeps/ieee754/dbl-64/e_gamma_r.c
index 7a2af31c46..adeb61a248 100644
--- a/sysdeps/ieee754/dbl-64/e_gamma_r.c
+++ b/sysdeps/ieee754/dbl-64/e_gamma_r.c
@@ -104,7 +104,7 @@ gamma_positive (double x, int *exp2_adj)
 		    * __ieee754_exp (-x_adj)
 		    * __ieee754_sqrt (2 * M_PI / x_adj)
 		    / prod);
-      exp_adj += x_eps * __ieee754_log (x);
+      exp_adj += x_eps * __ieee754_log (x_adj);
       double bsum = gamma_coeff[NCOEFF - 1];
       double x_adj2 = x_adj * x_adj;
       for (size_t i = 1; i <= NCOEFF - 1; i++)
@@ -119,6 +119,10 @@ __ieee754_gamma_r (double x, int *signgamp)
 {
   int32_t hx;
   u_int32_t lx;
+#if FLT_EVAL_METHOD != 0
+  volatile
+#endif
+  double ret;
 
   EXTRACT_WORDS (hx, lx, x);
 
@@ -153,36 +157,69 @@ __ieee754_gamma_r (double x, int *signgamp)
     {
       /* Overflow.  */
       *signgamp = 0;
-      return DBL_MAX * DBL_MAX;
+      ret = DBL_MAX * DBL_MAX;
+      return ret;
     }
-  else if (x > 0.0)
+  else
     {
-      *signgamp = 0;
-      int exp2_adj;
-      double ret = gamma_positive (x, &exp2_adj);
-      return __scalbn (ret, exp2_adj);
+      SET_RESTORE_ROUND (FE_TONEAREST);
+      if (x > 0.0)
+	{
+	  *signgamp = 0;
+	  int exp2_adj;
+	  double tret = gamma_positive (x, &exp2_adj);
+	  ret = __scalbn (tret, exp2_adj);
+	}
+      else if (x >= -DBL_EPSILON / 4.0)
+	{
+	  *signgamp = 0;
+	  ret = 1.0 / x;
+	}
+      else
+	{
+	  double tx = __trunc (x);
+	  *signgamp = (tx == 2.0 * __trunc (tx / 2.0)) ? -1 : 1;
+	  if (x <= -184.0)
+	    /* Underflow.  */
+	    ret = DBL_MIN * DBL_MIN;
+	  else
+	    {
+	      double frac = tx - x;
+	      if (frac > 0.5)
+		frac = 1.0 - frac;
+	      double sinpix = (frac <= 0.25
+			       ? __sin (M_PI * frac)
+			       : __cos (M_PI * (0.5 - frac)));
+	      int exp2_adj;
+	      double tret = M_PI / (-x * sinpix
+				    * gamma_positive (-x, &exp2_adj));
+	      ret = __scalbn (tret, -exp2_adj);
+	    }
+	}
     }
-  else if (x >= -DBL_EPSILON / 4.0)
+  if (isinf (ret) && x != 0)
     {
-      *signgamp = 0;
-      return 1.0 / x;
+      if (*signgamp < 0)
+	{
+	  ret = -__copysign (DBL_MAX, ret) * DBL_MAX;
+	  ret = -ret;
+	}
+      else
+	ret = __copysign (DBL_MAX, ret) * DBL_MAX;
+      return ret;
     }
-  else
+  else if (ret == 0)
     {
-      double tx = __trunc (x);
-      *signgamp = (tx == 2.0 * __trunc (tx / 2.0)) ? -1 : 1;
-      if (x <= -184.0)
-	/* Underflow.  */
-	return DBL_MIN * DBL_MIN;
-      double frac = tx - x;
-      if (frac > 0.5)
-	frac = 1.0 - frac;
-      double sinpix = (frac <= 0.25
-		       ? __sin (M_PI * frac)
-		       : __cos (M_PI * (0.5 - frac)));
-      int exp2_adj;
-      double ret = M_PI / (-x * sinpix * gamma_positive (-x, &exp2_adj));
-      return __scalbn (ret, -exp2_adj);
+      if (*signgamp < 0)
+	{
+	  ret = -__copysign (DBL_MIN, ret) * DBL_MIN;
+	  ret = -ret;
+	}
+      else
+	ret = __copysign (DBL_MIN, ret) * DBL_MIN;
+      return ret;
     }
+  else
+    return ret;
 }
 strong_alias (__ieee754_gamma_r, __gamma_r_finite)
diff --git a/sysdeps/ieee754/flt-32/e_gammaf_r.c b/sysdeps/ieee754/flt-32/e_gammaf_r.c
index ff67eca7d3..29fe8b46c2 100644
--- a/sysdeps/ieee754/flt-32/e_gammaf_r.c
+++ b/sysdeps/ieee754/flt-32/e_gammaf_r.c
@@ -97,7 +97,7 @@ gammaf_positive (float x, int *exp2_adj)
 		   * __ieee754_expf (-x_adj)
 		   * __ieee754_sqrtf (2 * (float) M_PI / x_adj)
 		   / prod);
-      exp_adj += x_eps * __ieee754_logf (x);
+      exp_adj += x_eps * __ieee754_logf (x_adj);
       float bsum = gamma_coeff[NCOEFF - 1];
       float x_adj2 = x_adj * x_adj;
       for (size_t i = 1; i <= NCOEFF - 1; i++)
@@ -111,6 +111,10 @@ float
 __ieee754_gammaf_r (float x, int *signgamp)
 {
   int32_t hx;
+#if FLT_EVAL_METHOD != 0
+  volatile
+#endif
+  float ret;
 
   GET_FLOAT_WORD (hx, x);
 
@@ -145,37 +149,69 @@ __ieee754_gammaf_r (float x, int *signgamp)
     {
       /* Overflow.  */
       *signgamp = 0;
-      return FLT_MAX * FLT_MAX;
+      ret = FLT_MAX * FLT_MAX;
+      return ret;
     }
-  else if (x > 0.0f)
+  else
     {
-      *signgamp = 0;
-      int exp2_adj;
-      float ret = gammaf_positive (x, &exp2_adj);
-      return __scalbnf (ret, exp2_adj);
+      SET_RESTORE_ROUNDF (FE_TONEAREST);
+      if (x > 0.0f)
+	{
+	  *signgamp = 0;
+	  int exp2_adj;
+	  float tret = gammaf_positive (x, &exp2_adj);
+	  ret = __scalbnf (tret, exp2_adj);
+	}
+      else if (x >= -FLT_EPSILON / 4.0f)
+	{
+	  *signgamp = 0;
+	  ret = 1.0f / x;
+	}
+      else
+	{
+	  float tx = __truncf (x);
+	  *signgamp = (tx == 2.0f * __truncf (tx / 2.0f)) ? -1 : 1;
+	  if (x <= -42.0f)
+	    /* Underflow.  */
+	    ret = FLT_MIN * FLT_MIN;
+	  else
+	    {
+	      float frac = tx - x;
+	      if (frac > 0.5f)
+		frac = 1.0f - frac;
+	      float sinpix = (frac <= 0.25f
+			      ? __sinf ((float) M_PI * frac)
+			      : __cosf ((float) M_PI * (0.5f - frac)));
+	      int exp2_adj;
+	      float tret = (float) M_PI / (-x * sinpix
+					   * gammaf_positive (-x, &exp2_adj));
+	      ret = __scalbnf (tret, -exp2_adj);
+	    }
+	}
     }
-  else if (x >= -FLT_EPSILON / 4.0f)
+  if (isinf (ret) && x != 0)
     {
-      *signgamp = 0;
-      return 1.0f / x;
+      if (*signgamp < 0)
+	{
+	  ret = -__copysignf (FLT_MAX, ret) * FLT_MAX;
+	  ret = -ret;
+	}
+      else
+	ret = __copysignf (FLT_MAX, ret) * FLT_MAX;
+      return ret;
     }
-  else
+  else if (ret == 0)
     {
-      float tx = __truncf (x);
-      *signgamp = (tx == 2.0f * __truncf (tx / 2.0f)) ? -1 : 1;
-      if (x <= -42.0f)
-	/* Underflow.  */
-	return FLT_MIN * FLT_MIN;
-      float frac = tx - x;
-      if (frac > 0.5f)
-	frac = 1.0f - frac;
-      float sinpix = (frac <= 0.25f
-		      ? __sinf ((float) M_PI * frac)
-		      : __cosf ((float) M_PI * (0.5f - frac)));
-      int exp2_adj;
-      float ret = (float) M_PI / (-x * sinpix
-				  * gammaf_positive (-x, &exp2_adj));
-      return __scalbnf (ret, -exp2_adj);
+      if (*signgamp < 0)
+	{
+	  ret = -__copysignf (FLT_MIN, ret) * FLT_MIN;
+	  ret = -ret;
+	}
+      else
+	ret = __copysignf (FLT_MIN, ret) * FLT_MIN;
+      return ret;
     }
+  else
+    return ret;
 }
 strong_alias (__ieee754_gammaf_r, __gammaf_r_finite)
diff --git a/sysdeps/ieee754/ldbl-128/e_gammal_r.c b/sysdeps/ieee754/ldbl-128/e_gammal_r.c
index 39c0638ac3..c51b050e0e 100644
--- a/sysdeps/ieee754/ldbl-128/e_gammal_r.c
+++ b/sysdeps/ieee754/ldbl-128/e_gammal_r.c
@@ -109,7 +109,7 @@ gammal_positive (long double x, int *exp2_adj)
 			 * __ieee754_expl (-x_adj)
 			 * __ieee754_sqrtl (2 * M_PIl / x_adj)
 			 / prod);
-      exp_adj += x_eps * __ieee754_logl (x);
+      exp_adj += x_eps * __ieee754_logl (x_adj);
       long double bsum = gamma_coeff[NCOEFF - 1];
       long double x_adj2 = x_adj * x_adj;
       for (size_t i = 1; i <= NCOEFF - 1; i++)
@@ -124,6 +124,7 @@ __ieee754_gammal_r (long double x, int *signgamp)
 {
   int64_t hx;
   u_int64_t lx;
+  long double ret;
 
   GET_LDOUBLE_WORDS64 (hx, lx, x);
 
@@ -159,35 +160,58 @@ __ieee754_gammal_r (long double x, int *signgamp)
       *signgamp = 0;
       return LDBL_MAX * LDBL_MAX;
     }
-  else if (x > 0.0L)
+  else
     {
-      *signgamp = 0;
-      int exp2_adj;
-      long double ret = gammal_positive (x, &exp2_adj);
-      return __scalbnl (ret, exp2_adj);
+      SET_RESTORE_ROUNDL (FE_TONEAREST);
+      if (x > 0.0L)
+	{
+	  *signgamp = 0;
+	  int exp2_adj;
+	  ret = gammal_positive (x, &exp2_adj);
+	  ret = __scalbnl (ret, exp2_adj);
+	}
+      else if (x >= -LDBL_EPSILON / 4.0L)
+	{
+	  *signgamp = 0;
+	  ret = 1.0L / x;
+	}
+      else
+	{
+	  long double tx = __truncl (x);
+	  *signgamp = (tx == 2.0L * __truncl (tx / 2.0L)) ? -1 : 1;
+	  if (x <= -1775.0L)
+	    /* Underflow.  */
+	    ret = LDBL_MIN * LDBL_MIN;
+	  else
+	    {
+	      long double frac = tx - x;
+	      if (frac > 0.5L)
+		frac = 1.0L - frac;
+	      long double sinpix = (frac <= 0.25L
+				    ? __sinl (M_PIl * frac)
+				    : __cosl (M_PIl * (0.5L - frac)));
+	      int exp2_adj;
+	      ret = M_PIl / (-x * sinpix
+			     * gammal_positive (-x, &exp2_adj));
+	      ret = __scalbnl (ret, -exp2_adj);
+	    }
+	}
     }
-  else if (x >= -LDBL_EPSILON / 4.0L)
+  if (isinf (ret) && x != 0)
     {
-      *signgamp = 0;
-      return 1.0f / x;
+      if (*signgamp < 0)
+	return -(-__copysignl (LDBL_MAX, ret) * LDBL_MAX);
+      else
+	return __copysignl (LDBL_MAX, ret) * LDBL_MAX;
     }
-  else
+  else if (ret == 0)
     {
-      long double tx = __truncl (x);
-      *signgamp = (tx == 2.0L * __truncl (tx / 2.0L)) ? -1 : 1;
-      if (x <= -1775.0L)
-	/* Underflow.  */
-	return LDBL_MIN * LDBL_MIN;
-      long double frac = tx - x;
-      if (frac > 0.5L)
-	frac = 1.0L - frac;
-      long double sinpix = (frac <= 0.25L
-			    ? __sinl (M_PIl * frac)
-			    : __cosl (M_PIl * (0.5L - frac)));
-      int exp2_adj;
-      long double ret = M_PIl / (-x * sinpix
-				 * gammal_positive (-x, &exp2_adj));
-      return __scalbnl (ret, -exp2_adj);
+      if (*signgamp < 0)
+	return -(-__copysignl (LDBL_MIN, ret) * LDBL_MIN);
+      else
+	return __copysignl (LDBL_MIN, ret) * LDBL_MIN;
     }
+  else
+    return ret;
 }
 strong_alias (__ieee754_gammal_r, __gammal_r_finite)
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c b/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
index 1322bb0ea3..48098c18f6 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c
@@ -108,7 +108,7 @@ gammal_positive (long double x, int *exp2_adj)
 			 * __ieee754_expl (-x_adj)
 			 * __ieee754_sqrtl (2 * M_PIl / x_adj)
 			 / prod);
-      exp_adj += x_eps * __ieee754_logl (x);
+      exp_adj += x_eps * __ieee754_logl (x_adj);
       long double bsum = gamma_coeff[NCOEFF - 1];
       long double x_adj2 = x_adj * x_adj;
       for (size_t i = 1; i <= NCOEFF - 1; i++)
@@ -123,6 +123,7 @@ __ieee754_gammal_r (long double x, int *signgamp)
 {
   int64_t hx;
   double xhi;
+  long double ret;
 
   xhi = ldbl_high (x);
   EXTRACT_WORDS64 (hx, xhi);
@@ -159,35 +160,58 @@ __ieee754_gammal_r (long double x, int *signgamp)
       *signgamp = 0;
       return LDBL_MAX * LDBL_MAX;
     }
-  else if (x > 0.0L)
+  else
     {
-      *signgamp = 0;
-      int exp2_adj;
-      long double ret = gammal_positive (x, &exp2_adj);
-      return __scalbnl (ret, exp2_adj);
+      SET_RESTORE_ROUNDL (FE_TONEAREST);
+      if (x > 0.0L)
+	{
+	  *signgamp = 0;
+	  int exp2_adj;
+	  ret = gammal_positive (x, &exp2_adj);
+	  ret = __scalbnl (ret, exp2_adj);
+	}
+      else if (x >= -0x1p-110L)
+	{
+	  *signgamp = 0;
+	  ret = 1.0L / x;
+	}
+      else
+	{
+	  long double tx = __truncl (x);
+	  *signgamp = (tx == 2.0L * __truncl (tx / 2.0L)) ? -1 : 1;
+	  if (x <= -191.0L)
+	    /* Underflow.  */
+	    ret = LDBL_MIN * LDBL_MIN;
+	  else
+	    {
+	      long double frac = tx - x;
+	      if (frac > 0.5L)
+		frac = 1.0L - frac;
+	      long double sinpix = (frac <= 0.25L
+				    ? __sinl (M_PIl * frac)
+				    : __cosl (M_PIl * (0.5L - frac)));
+	      int exp2_adj;
+	      ret = M_PIl / (-x * sinpix
+			     * gammal_positive (-x, &exp2_adj));
+	      ret = __scalbnl (ret, -exp2_adj);
+	    }
+	}
     }
-  else if (x >= -0x1p-110L)
+  if (isinf (ret) && x != 0)
     {
-      *signgamp = 0;
-      return 1.0f / x;
+      if (*signgamp < 0)
+	return -(-__copysignl (LDBL_MAX, ret) * LDBL_MAX);
+      else
+	return __copysignl (LDBL_MAX, ret) * LDBL_MAX;
     }
-  else
+  else if (ret == 0)
     {
-      long double tx = __truncl (x);
-      *signgamp = (tx == 2.0L * __truncl (tx / 2.0L)) ? -1 : 1;
-      if (x <= -191.0L)
-	/* Underflow.  */
-	return LDBL_MIN * LDBL_MIN;
-      long double frac = tx - x;
-      if (frac > 0.5L)
-	frac = 1.0L - frac;
-      long double sinpix = (frac <= 0.25L
-			    ? __sinl (M_PIl * frac)
-			    : __cosl (M_PIl * (0.5L - frac)));
-      int exp2_adj;
-      long double ret = M_PIl / (-x * sinpix
-				 * gammal_positive (-x, &exp2_adj));
-      return __scalbnl (ret, -exp2_adj);
+      if (*signgamp < 0)
+	return -(-__copysignl (LDBL_MIN, ret) * LDBL_MIN);
+      else
+	return __copysignl (LDBL_MIN, ret) * LDBL_MIN;
     }
+  else
+    return ret;
 }
 strong_alias (__ieee754_gammal_r, __gammal_r_finite)
diff --git a/sysdeps/ieee754/ldbl-96/e_gammal_r.c b/sysdeps/ieee754/ldbl-96/e_gammal_r.c
index 800522b7c8..9da5db33f0 100644
--- a/sysdeps/ieee754/ldbl-96/e_gammal_r.c
+++ b/sysdeps/ieee754/ldbl-96/e_gammal_r.c
@@ -102,7 +102,7 @@ gammal_positive (long double x, int *exp2_adj)
 			 * __ieee754_expl (-x_adj)
 			 * __ieee754_sqrtl (2 * M_PIl / x_adj)
 			 / prod);
-      exp_adj += x_eps * __ieee754_logl (x);
+      exp_adj += x_eps * __ieee754_logl (x_adj);
       long double bsum = gamma_coeff[NCOEFF - 1];
       long double x_adj2 = x_adj * x_adj;
       for (size_t i = 1; i <= NCOEFF - 1; i++)
@@ -116,6 +116,7 @@ long double
 __ieee754_gammal_r (long double x, int *signgamp)
 {
   u_int32_t es, hx, lx;
+  long double ret;
 
   GET_LDOUBLE_WORDS (es, hx, lx, x);
 
@@ -151,35 +152,58 @@ __ieee754_gammal_r (long double x, int *signgamp)
       *signgamp = 0;
       return LDBL_MAX * LDBL_MAX;
     }
-  else if (x > 0.0L)
+  else
     {
-      *signgamp = 0;
-      int exp2_adj;
-      long double ret = gammal_positive (x, &exp2_adj);
-      return __scalbnl (ret, exp2_adj);
+      SET_RESTORE_ROUNDL (FE_TONEAREST);
+      if (x > 0.0L)
+	{
+	  *signgamp = 0;
+	  int exp2_adj;
+	  ret = gammal_positive (x, &exp2_adj);
+	  ret = __scalbnl (ret, exp2_adj);
+	}
+      else if (x >= -LDBL_EPSILON / 4.0L)
+	{
+	  *signgamp = 0;
+	  ret = 1.0L / x;
+	}
+      else
+	{
+	  long double tx = __truncl (x);
+	  *signgamp = (tx == 2.0L * __truncl (tx / 2.0L)) ? -1 : 1;
+	  if (x <= -1766.0L)
+	    /* Underflow.  */
+	    ret = LDBL_MIN * LDBL_MIN;
+	  else
+	    {
+	      long double frac = tx - x;
+	      if (frac > 0.5L)
+		frac = 1.0L - frac;
+	      long double sinpix = (frac <= 0.25L
+				    ? __sinl (M_PIl * frac)
+				    : __cosl (M_PIl * (0.5L - frac)));
+	      int exp2_adj;
+	      ret = M_PIl / (-x * sinpix
+			     * gammal_positive (-x, &exp2_adj));
+	      ret = __scalbnl (ret, -exp2_adj);
+	    }
+	}
     }
-  else if (x >= -LDBL_EPSILON / 4.0L)
+  if (isinf (ret) && x != 0)
     {
-      *signgamp = 0;
-      return 1.0f / x;
+      if (*signgamp < 0)
+	return -(-__copysignl (LDBL_MAX, ret) * LDBL_MAX);
+      else
+	return __copysignl (LDBL_MAX, ret) * LDBL_MAX;
     }
-  else
+  else if (ret == 0)
     {
-      long double tx = __truncl (x);
-      *signgamp = (tx == 2.0L * __truncl (tx / 2.0L)) ? -1 : 1;
-      if (x <= -1766.0L)
-	/* Underflow.  */
-	return LDBL_MIN * LDBL_MIN;
-      long double frac = tx - x;
-      if (frac > 0.5L)
-	frac = 1.0L - frac;
-      long double sinpix = (frac <= 0.25L
-			    ? __sinl (M_PIl * frac)
-			    : __cosl (M_PIl * (0.5L - frac)));
-      int exp2_adj;
-      long double ret = M_PIl / (-x * sinpix
-				 * gammal_positive (-x, &exp2_adj));
-      return __scalbnl (ret, -exp2_adj);
+      if (*signgamp < 0)
+	return -(-__copysignl (LDBL_MIN, ret) * LDBL_MIN);
+      else
+	return __copysignl (LDBL_MIN, ret) * LDBL_MIN;
     }
+  else
+    return ret;
 }
 strong_alias (__ieee754_gammal_r, __gammal_r_finite)
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index 12d0c5a7db..de7d420aef 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -2222,12 +2222,36 @@ ildouble: 4
 ldouble: 4
 
 Function: "tgamma":
-double: 9
+double: 4
 float: 5
-idouble: 9
+idouble: 4
 ifloat: 5
-ildouble: 6
-ldouble: 6
+ildouble: 3
+ldouble: 3
+
+Function: "tgamma_downward":
+double: 4
+float: 4
+idouble: 4
+ifloat: 4
+ildouble: 3
+ldouble: 3
+
+Function: "tgamma_towardzero":
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 3
+ldouble: 3
+
+Function: "tgamma_upward":
+double: 5
+float: 5
+idouble: 5
+ifloat: 5
+ildouble: 3
+ldouble: 3
 
 Function: "y0":
 double: 2