mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 17:53:37 +08:00
Add inlining of the C99 math functions isinf/isnan/signbit/isfinite/isnormal/fpclassify using GCC
built-ins when available. Since going through the PLT is expensive for these small functions, inlining results in major speedups (about 7x on Cortex-A57 for isinf). The GCC built-ins are not correct if signalling NaN support is required, and thus are turned off in that case (see GCC bug 66462). The test-snan.c tests sNaNs and so must be explicitly built with -fsignaling-nans. 2015-09-18 Wilco Dijkstra <wdijkstr@arm.com> [BZ #15367] [BZ #17441] * math/Makefile: Build test-snan.c with -fsignaling-nans. * math/math.h (fpclassify): Use __builtin_fpclassify when available. (signbit): Use __builtin_signbit(f/l). (isfinite): Use__builtin_isfinite. (isnormal): Use __builtin_isnormal. (isnan): Use __builtin_isnan. (isinf): Use __builtin_isinf_sign.
This commit is contained in:
parent
cb2f668d46
commit
8df4e219e4
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
||||
2015-09-18 Wilco Dijkstra <wdijkstr@arm.com>
|
||||
|
||||
[BZ #15367]
|
||||
[BZ #17441]
|
||||
|
||||
* math/Makefile: Build test-snan.c with -fsignaling-nans.
|
||||
* math/math.h (fpclassify): Use __builtin_fpclassify when
|
||||
available. (signbit): Use __builtin_signbit(f/l).
|
||||
(isfinite): Use__builtin_isfinite. (isnormal): Use
|
||||
__builtin_isnormal. (isnan): Use __builtin_isnan.
|
||||
(isinf): Use __builtin_isinf_sign.
|
||||
|
||||
2015-09-18 Wilco Dijkstra <wdijkstr@arm.com>
|
||||
|
||||
* benchtests/Makefile: Add bench-math-inlines, link with libm.
|
||||
|
15
NEWS
15
NEWS
@ -9,13 +9,14 @@ Version 2.23
|
||||
|
||||
* The following bugs are resolved with this release:
|
||||
|
||||
2542, 2543, 2558, 2898, 4404, 6803, 14341, 14912, 15384, 15786, 15918,
|
||||
16141, 16296, 16415, 16517, 16519, 16520, 16521, 16734, 16973, 16985,
|
||||
17118, 17243, 17244, 17787, 17886, 17887, 17905, 18084, 18086, 18240,
|
||||
18265, 18370, 18421, 18480, 18525, 18595, 18610, 18618, 18647, 18661,
|
||||
18674, 18675, 18681, 18757, 18778, 18781, 18787, 18789, 18790, 18795,
|
||||
18796, 18820, 18823, 18824, 18857, 18863, 18870, 18872, 18873, 18875,
|
||||
18887, 18921, 18951, 18952, 18961, 18966, 18967, 18970, 18977.
|
||||
2542, 2543, 2558, 2898, 4404, 6803, 14341, 14912, 15367, 15384, 15786,
|
||||
15918, 16141, 16296, 16415, 16517, 16519, 16520, 16521, 16734, 16973,
|
||||
16985, 17118, 17243, 17244, 17441, 17787, 17886, 17887, 17905, 18084,
|
||||
18086, 18240, 18265, 18370, 18421, 18480, 18525, 18595, 18610, 18618,
|
||||
18647, 18661, 18674, 18675, 18681, 18757, 18778, 18781, 18787, 18789,
|
||||
18790, 18795, 18796, 18820, 18823, 18824, 18857, 18863, 18870, 18872,
|
||||
18873, 18875, 18887, 18921, 18951, 18952, 18961, 18966, 18967, 18970,
|
||||
18977.
|
||||
|
||||
* The obsolete header <regexp.h> has been removed. Programs that require
|
||||
this header must be updated to use <regex.h> instead.
|
||||
|
@ -176,6 +176,8 @@ CFLAGS-test-tgmath.c = -fno-builtin
|
||||
CFLAGS-test-tgmath2.c = -fno-builtin
|
||||
CFLAGS-test-tgmath-ret.c = -fno-builtin
|
||||
CFLAGS-test-powl.c = -fno-builtin
|
||||
|
||||
CFLAGS-test-snan.c = -fsignaling-nans
|
||||
CPPFLAGS-test-ifloat.c = -U__LIBC_INTERNAL_MATH_INLINES \
|
||||
$(libm-test-fast-math-cflags)
|
||||
CPPFLAGS-test-idouble.c = -U__LIBC_INTERNAL_MATH_INLINES \
|
||||
@ -183,7 +185,6 @@ CPPFLAGS-test-idouble.c = -U__LIBC_INTERNAL_MATH_INLINES \
|
||||
CPPFLAGS-test-ildoubl.c = -U__LIBC_INTERNAL_MATH_INLINES \
|
||||
$(libm-test-fast-math-cflags)
|
||||
|
||||
|
||||
# The -lieee module sets the _LIB_VERSION_ switch to IEEE mode
|
||||
# for error handling in the -lm functions.
|
||||
install-lib += libieee.a
|
||||
|
42
math/math.h
42
math/math.h
@ -225,8 +225,16 @@ enum
|
||||
FP_NORMAL
|
||||
};
|
||||
|
||||
/* GCC bug 66462 means we cannot use the math builtins with -fsignaling-nan,
|
||||
so disable builtins if this is enabled. When fixed in a newer GCC,
|
||||
the __SUPPORT_SNAN__ check may be skipped for those versions. */
|
||||
|
||||
/* Return number of classification appropriate for X. */
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ \
|
||||
&& !defined __OPTIMIZE_SIZE__
|
||||
# define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE, \
|
||||
FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
|
||||
# elif defined __NO_LONG_DOUBLE_MATH
|
||||
# define fpclassify(x) \
|
||||
(sizeof (x) == sizeof (float) ? __fpclassifyf (x) : __fpclassify (x))
|
||||
# else
|
||||
@ -238,19 +246,29 @@ enum
|
||||
# endif
|
||||
|
||||
/* Return nonzero value if sign of X is negative. */
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# if __GNUC_PREREQ (4,0)
|
||||
# define signbit(x) \
|
||||
(sizeof (x) == sizeof (float) ? __signbitf (x) : __signbit (x))
|
||||
(sizeof (x) == sizeof (float) \
|
||||
? __builtin_signbitf (x) \
|
||||
: sizeof (x) == sizeof (double) \
|
||||
? __builtin_signbit (x) : __builtin_signbitl (x))
|
||||
# else
|
||||
# define signbit(x) \
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# define signbit(x) \
|
||||
(sizeof (x) == sizeof (float) ? __signbitf (x) : __signbit (x))
|
||||
# else
|
||||
# define signbit(x) \
|
||||
(sizeof (x) == sizeof (float) \
|
||||
? __signbitf (x) \
|
||||
: sizeof (x) == sizeof (double) \
|
||||
? __signbit (x) : __signbitl (x))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Return nonzero value if X is not +-Inf or NaN. */
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__
|
||||
# define isfinite(x) __builtin_isfinite (x)
|
||||
# elif defined __NO_LONG_DOUBLE_MATH
|
||||
# define isfinite(x) \
|
||||
(sizeof (x) == sizeof (float) ? __finitef (x) : __finite (x))
|
||||
# else
|
||||
@ -262,11 +280,17 @@ enum
|
||||
# endif
|
||||
|
||||
/* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */
|
||||
# define isnormal(x) (fpclassify (x) == FP_NORMAL)
|
||||
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__
|
||||
# define isnormal(x) __builtin_isnormal (x)
|
||||
# else
|
||||
# define isnormal(x) (fpclassify (x) == FP_NORMAL)
|
||||
# endif
|
||||
|
||||
/* Return nonzero value if X is a NaN. We could use `fpclassify' but
|
||||
we already have this functions `__isnan' and it is faster. */
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__
|
||||
# define isnan(x) __builtin_isnan (x)
|
||||
# elif defined __NO_LONG_DOUBLE_MATH
|
||||
# define isnan(x) \
|
||||
(sizeof (x) == sizeof (float) ? __isnanf (x) : __isnan (x))
|
||||
# else
|
||||
@ -278,7 +302,9 @@ enum
|
||||
# endif
|
||||
|
||||
/* Return nonzero value if X is positive or negative infinity. */
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__
|
||||
# define isinf(x) __builtin_isinf_sign (x)
|
||||
# elif defined __NO_LONG_DOUBLE_MATH
|
||||
# define isinf(x) \
|
||||
(sizeof (x) == sizeof (float) ? __isinff (x) : __isinf (x))
|
||||
# else
|
||||
|
Loading…
Reference in New Issue
Block a user