Fix ldbl-128ibm expl overflow in non-default rounding modes (bug 19078).

The ldbl-128ibm expl wrapper checks the argument to determine when to
call __kernel_standard_l, thereby overriding overflowing results from
__ieee754_expl that could otherwise (given appropriately patched
libgcc) be correct for the rounding mode.  This patch changes it to
check the result of __ieee754_expl instead, as other versions of this
wrapper do.

Tested for powerpc.

	[BZ #19078]
	* sysdeps/ieee754/ldbl-128ibm/w_expl.c (o_thres): Remove variable.
	(u_thres): Likewise.
	(__expl): Determine whether to call __kernel_standard_l based on
	value of result, not argument.
This commit is contained in:
Joseph Myers 2015-10-06 17:37:49 +00:00
parent b3364d0589
commit 6c9678ebd4
3 changed files with 9 additions and 6 deletions

View File

@ -1,5 +1,11 @@
2015-10-06 Joseph Myers <joseph@codesourcery.com>
[BZ #19078]
* sysdeps/ieee754/ldbl-128ibm/w_expl.c (o_thres): Remove variable.
(u_thres): Likewise.
(__expl): Determine whether to call __kernel_standard_l based on
value of result, not argument.
* math/libm-test.inc (scalb_test_data): Add more expectations for
the "inexact" exception.

2
NEWS
View File

@ -18,7 +18,7 @@ Version 2.23
18820, 18823, 18824, 18825, 18857, 18863, 18870, 18872, 18873, 18875,
18887, 18921, 18951, 18952, 18956, 18961, 18966, 18967, 18969, 18970,
18977, 18980, 18981, 18985, 19003, 19012, 19016, 19018, 19032, 19046,
19049, 19050, 19059, 19071, 19076, 19077.
19049, 19050, 19059, 19071, 19076, 19077, 19078.
* The obsolete header <regexp.h> has been removed. Programs that require
this header must be updated to use <regex.h> instead.

View File

@ -2,9 +2,6 @@
#include <math_private.h>
#include <math_ldbl_opt.h>
static const long double o_thres = 709.78271289338399678773454114191496482L;
static const long double u_thres = -744.44007192138126231410729844608163411L;
long double __expl(long double x) /* wrapper exp */
{
long double z;
@ -13,9 +10,9 @@ long double __expl(long double x) /* wrapper exp */
return z;
if (isfinite(x))
{
if (x >= o_thres)
if (!isfinite (z))
return __kernel_standard_l(x,x,206); /* exp overflow */
else if (x <= u_thres)
else if (z == 0.0L)
return __kernel_standard_l(x,x,207); /* exp underflow */
}
return z;