mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-14 20:01:03 +03:00
S/390: Do not raise inexact exception in lrint/lround. [BZ #19486]
I get some math test-failures on s390 for float/double/ldouble for various lrint/lround functions like: lrint (0x1p64): Exception "Inexact" set lrint (-0x1p64): Exception "Inexact" set lround (0x1p64): Exception "Inexact" set lround (-0x1p64): Exception "Inexact" set ... GCC emits "convert to fixed" instructions for casting floating point values to integer values. These instructions raise invalid and inexact exceptions if the floating point value exceeds the integer type ranges. This patch enables the various FIX_DBL_LONG_CONVERT_OVERFLOW macros in order to avoid a cast from floating point to integer type and raise the invalid exception with feraiseexcept. The ldbl-128 rint/round functions are now using the same logic. ChangeLog: [BZ #19486] * sysdeps/s390/fix-fp-int-convert-overflow.h: New File. * sysdeps/generic/fix-fp-int-convert-overflow.h (FIX_LDBL_LONG_CONVERT_OVERFLOW, FIX_LDBL_LLONG_CONVERT_OVERFLOW): New define. * sysdeps/arm/fix-fp-int-convert-overflow.h: Likewise. * sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h: Likewise. * sysdeps/ieee754/ldbl-128/s_lrintl.c (__lrintl): Avoid conversions to long int where inexact exceptions could be raised. * sysdeps/ieee754/ldbl-128/s_lroundl.c (__lroundl): Likewise. * sysdeps/ieee754/ldbl-128/s_llrintl.c (__llrintl): Avoid conversions to long long int where inexact exceptions could be raised. * sysdeps/ieee754/ldbl-128/s_llroundl.c (__llroundl): Likewise.
This commit is contained in:
21
ChangeLog
21
ChangeLog
@ -1,3 +1,24 @@
|
|||||||
|
2016-01-15 Stefan Liebler <stli@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
[BZ #19486]
|
||||||
|
* sysdeps/s390/fix-fp-int-convert-overflow.h: New File.
|
||||||
|
* sysdeps/generic/fix-fp-int-convert-overflow.h
|
||||||
|
(FIX_LDBL_LONG_CONVERT_OVERFLOW,
|
||||||
|
FIX_LDBL_LLONG_CONVERT_OVERFLOW): New define.
|
||||||
|
* sysdeps/arm/fix-fp-int-convert-overflow.h: Likewise.
|
||||||
|
* sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h:
|
||||||
|
Likewise.
|
||||||
|
* sysdeps/ieee754/ldbl-128/s_lrintl.c (__lrintl):
|
||||||
|
Avoid conversions to long int where inexact exceptions
|
||||||
|
could be raised.
|
||||||
|
* sysdeps/ieee754/ldbl-128/s_lroundl.c (__lroundl):
|
||||||
|
Likewise.
|
||||||
|
* sysdeps/ieee754/ldbl-128/s_llrintl.c (__llrintl):
|
||||||
|
Avoid conversions to long long int where inexact exceptions
|
||||||
|
could be raised.
|
||||||
|
* sysdeps/ieee754/ldbl-128/s_llroundl.c (__llroundl):
|
||||||
|
Likewise.
|
||||||
|
|
||||||
2016-01-17 Mike Frysinger <vapier@gentoo.org>
|
2016-01-17 Mike Frysinger <vapier@gentoo.org>
|
||||||
|
|
||||||
* configure.ac: Rewrite error comment and use AC_MSG_ERROR.
|
* configure.ac: Rewrite error comment and use AC_MSG_ERROR.
|
||||||
|
@ -25,8 +25,10 @@
|
|||||||
see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>). */
|
see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>). */
|
||||||
#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1
|
#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1
|
||||||
#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1
|
#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1
|
||||||
|
#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 0
|
||||||
|
|
||||||
#define FIX_FLT_LONG_CONVERT_OVERFLOW 0
|
#define FIX_FLT_LONG_CONVERT_OVERFLOW 0
|
||||||
#define FIX_DBL_LONG_CONVERT_OVERFLOW 0
|
#define FIX_DBL_LONG_CONVERT_OVERFLOW 0
|
||||||
|
#define FIX_LDBL_LONG_CONVERT_OVERFLOW 0
|
||||||
|
|
||||||
#endif /* fix-fp-int-convert-overflow.h */
|
#endif /* fix-fp-int-convert-overflow.h */
|
||||||
|
@ -27,5 +27,7 @@
|
|||||||
#define FIX_FLT_LLONG_CONVERT_OVERFLOW 0
|
#define FIX_FLT_LLONG_CONVERT_OVERFLOW 0
|
||||||
#define FIX_DBL_LONG_CONVERT_OVERFLOW 0
|
#define FIX_DBL_LONG_CONVERT_OVERFLOW 0
|
||||||
#define FIX_DBL_LLONG_CONVERT_OVERFLOW 0
|
#define FIX_DBL_LLONG_CONVERT_OVERFLOW 0
|
||||||
|
#define FIX_LDBL_LONG_CONVERT_OVERFLOW 0
|
||||||
|
#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 0
|
||||||
|
|
||||||
#endif /* fix-fp-int-convert-overflow.h */
|
#endif /* fix-fp-int-convert-overflow.h */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <math_private.h>
|
#include <math_private.h>
|
||||||
|
#include <fix-fp-int-convert-overflow.h>
|
||||||
|
|
||||||
static const long double two112[2] =
|
static const long double two112[2] =
|
||||||
{
|
{
|
||||||
@ -91,6 +92,12 @@ __llrintl (long double x)
|
|||||||
feraiseexcept (t == LLONG_MIN ? FE_INEXACT : FE_INVALID);
|
feraiseexcept (t == LLONG_MIN ? FE_INEXACT : FE_INVALID);
|
||||||
return LLONG_MIN;
|
return LLONG_MIN;
|
||||||
}
|
}
|
||||||
|
else if (FIX_LDBL_LLONG_CONVERT_OVERFLOW && x != (long double) LLONG_MIN)
|
||||||
|
{
|
||||||
|
feraiseexcept (FE_INVALID);
|
||||||
|
return sx == 0 ? LLONG_MAX : LLONG_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return (long long int) x;
|
return (long long int) x;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <math_private.h>
|
#include <math_private.h>
|
||||||
|
#include <fix-fp-int-convert-overflow.h>
|
||||||
|
|
||||||
long long int
|
long long int
|
||||||
__llroundl (long double x)
|
__llroundl (long double x)
|
||||||
@ -78,7 +78,14 @@ __llroundl (long double x)
|
|||||||
FE_INVALID must be raised and the return value is
|
FE_INVALID must be raised and the return value is
|
||||||
unspecified. */
|
unspecified. */
|
||||||
#ifdef FE_INVALID
|
#ifdef FE_INVALID
|
||||||
if (x <= (long double) LLONG_MIN - 0.5L)
|
if (FIX_LDBL_LLONG_CONVERT_OVERFLOW
|
||||||
|
&& !(sign == -1 && x > (long double) LLONG_MIN - 0.5L))
|
||||||
|
{
|
||||||
|
feraiseexcept (FE_INVALID);
|
||||||
|
return sign == 1 ? LLONG_MAX : LLONG_MIN;
|
||||||
|
}
|
||||||
|
else if (!FIX_LDBL_LLONG_CONVERT_OVERFLOW
|
||||||
|
&& x <= (long double) LLONG_MIN - 0.5L)
|
||||||
{
|
{
|
||||||
/* If truncation produces LLONG_MIN, the cast will not raise
|
/* If truncation produces LLONG_MIN, the cast will not raise
|
||||||
the exception, but may raise "inexact". */
|
the exception, but may raise "inexact". */
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <math_private.h>
|
#include <math_private.h>
|
||||||
|
#include <fix-fp-int-convert-overflow.h>
|
||||||
|
|
||||||
static const long double two112[2] =
|
static const long double two112[2] =
|
||||||
{
|
{
|
||||||
@ -120,6 +121,12 @@ __lrintl (long double x)
|
|||||||
feraiseexcept (t == LONG_MIN ? FE_INEXACT : FE_INVALID);
|
feraiseexcept (t == LONG_MIN ? FE_INEXACT : FE_INVALID);
|
||||||
return LONG_MIN;
|
return LONG_MIN;
|
||||||
}
|
}
|
||||||
|
else if (FIX_LDBL_LONG_CONVERT_OVERFLOW && x != (long double) LONG_MIN)
|
||||||
|
{
|
||||||
|
feraiseexcept (FE_INVALID);
|
||||||
|
return sx == 0 ? LONG_MAX : LONG_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return (long int) x;
|
return (long int) x;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <math_private.h>
|
#include <math_private.h>
|
||||||
|
#include <fix-fp-int-convert-overflow.h>
|
||||||
|
|
||||||
long int
|
long int
|
||||||
__lroundl (long double x)
|
__lroundl (long double x)
|
||||||
@ -87,7 +87,14 @@ __lroundl (long double x)
|
|||||||
FE_INVALID must be raised and the return value is
|
FE_INVALID must be raised and the return value is
|
||||||
unspecified. */
|
unspecified. */
|
||||||
#ifdef FE_INVALID
|
#ifdef FE_INVALID
|
||||||
if (x <= (long double) LONG_MIN - 0.5L)
|
if (FIX_LDBL_LONG_CONVERT_OVERFLOW
|
||||||
|
&& !(sign == -1 && x > (long double) LONG_MIN - 0.5L))
|
||||||
|
{
|
||||||
|
feraiseexcept (FE_INVALID);
|
||||||
|
return sign == 1 ? LONG_MAX : LONG_MIN;
|
||||||
|
}
|
||||||
|
else if (!FIX_LDBL_LONG_CONVERT_OVERFLOW
|
||||||
|
&& x <= (long double) LONG_MIN - 0.5L)
|
||||||
{
|
{
|
||||||
/* If truncation produces LONG_MIN, the cast will not raise
|
/* If truncation produces LONG_MIN, the cast will not raise
|
||||||
the exception, but may raise "inexact". */
|
the exception, but may raise "inexact". */
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>). */
|
see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>). */
|
||||||
#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1
|
#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1
|
||||||
#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1
|
#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1
|
||||||
|
#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 0
|
||||||
|
|
||||||
/* As of GCC 5 and binutils 2.25, for MIPS I GCC generates calls to
|
/* As of GCC 5 and binutils 2.25, for MIPS I GCC generates calls to
|
||||||
assembler macros for conversions from floating point to integer
|
assembler macros for conversions from floating point to integer
|
||||||
@ -32,5 +33,6 @@
|
|||||||
lose exceptions. */
|
lose exceptions. */
|
||||||
#define FIX_FLT_LONG_CONVERT_OVERFLOW (__mips == 1)
|
#define FIX_FLT_LONG_CONVERT_OVERFLOW (__mips == 1)
|
||||||
#define FIX_DBL_LONG_CONVERT_OVERFLOW (__mips == 1)
|
#define FIX_DBL_LONG_CONVERT_OVERFLOW (__mips == 1)
|
||||||
|
#define FIX_LDBL_LONG_CONVERT_OVERFLOW 0
|
||||||
|
|
||||||
#endif /* fix-fp-int-convert-overflow.h */
|
#endif /* fix-fp-int-convert-overflow.h */
|
||||||
|
33
sysdeps/s390/fix-fp-int-convert-overflow.h
Normal file
33
sysdeps/s390/fix-fp-int-convert-overflow.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* Fix for conversion of floating point to integer overflow. S390 version.
|
||||||
|
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef FIX_FP_INT_CONVERT_OVERFLOW_H
|
||||||
|
#define FIX_FP_INT_CONVERT_OVERFLOW_H 1
|
||||||
|
|
||||||
|
/* GCC emits "convert to fixed" instructions for casting floating point values
|
||||||
|
to integer values. These instructions raise invalid and inexact exceptions
|
||||||
|
if the floating point value exceeds the integer type ranges. */
|
||||||
|
#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1
|
||||||
|
#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1
|
||||||
|
#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 1
|
||||||
|
|
||||||
|
#define FIX_FLT_LONG_CONVERT_OVERFLOW 1
|
||||||
|
#define FIX_DBL_LONG_CONVERT_OVERFLOW 1
|
||||||
|
#define FIX_LDBL_LONG_CONVERT_OVERFLOW 1
|
||||||
|
|
||||||
|
#endif /* fix-fp-int-convert-overflow.h */
|
Reference in New Issue
Block a user