Message ID | 20190201124817.11211-1-adhemerval.zanella@linaro.org |
---|---|
State | Accepted |
Commit | 4997e8f31e7415652c3dedec672c0e9bf8caa9ca |
Headers | show |
Series | math: Enable some math builtins for clang | expand |
Ping. On 01/02/2019 10:48, Adhemerval Zanella wrote: > This patch enable the builtin usage for clang for the C99 functions > fpclassify, isfinite, isnormal, isnan, isinf, and sigbit. This allows > clang optimize the calls on frontend instead of call the appropriate > glibc symbols. > > Checked on aarch64-linux-gnu and x86_64-linux-gnu. I checked the supported > version for each builtin based on released version from clang/llvm. > > * math/math.h (fpclassify, isfinite, isnormal, isnan): Use builtin for > clang 2.8. > (signbit): Use builtin for clang 3.3. > (isinf): Use builtin for clang 3.7. > --- > ChangeLog | 7 +++++++ > math/math.h | 17 +++++++++++------ > 2 files changed, 18 insertions(+), 6 deletions(-) > > diff --git a/math/math.h b/math/math.h > index ffbc24af09..d70ec3877c 100644 > --- a/math/math.h > +++ b/math/math.h > @@ -874,7 +874,8 @@ enum > the __SUPPORT_SNAN__ check may be skipped for those versions. */ > > /* Return number of classification appropriate for X. */ > -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ \ > +# if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ > + || __glibc_clang_prereq (2,8)) \ > && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus) > /* The check for __cplusplus allows the use of the builtin, even > when optimization for size is on. This is provided for > @@ -889,7 +890,7 @@ enum > # endif > > /* Return nonzero value if sign of X is negative. */ > -# if __GNUC_PREREQ (6,0) > +# if __GNUC_PREREQ (6,0) || __glibc_clang_prereq (3,3) > # define signbit(x) __builtin_signbit (x) > # elif defined __cplusplus > /* In C++ mode, __MATH_TG cannot be used, because it relies on > @@ -907,14 +908,16 @@ enum > # endif > > /* Return nonzero value if X is not +-Inf or NaN. */ > -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ > +# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ > + || __glibc_clang_prereq (2,8) > # define isfinite(x) __builtin_isfinite (x) > # else > # define isfinite(x) __MATH_TG ((x), __finite, (x)) > # endif > > /* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ > -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ > +# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ > + || __glibc_clang_prereq (2,8) > # define isnormal(x) __builtin_isnormal (x) > # else > # define isnormal(x) (fpclassify (x) == FP_NORMAL) > @@ -922,7 +925,8 @@ enum > > /* Return nonzero value if X is a NaN. We could use `fpclassify' but > we already have this functions `__isnan' and it is faster. */ > -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ > +# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ > + || __glibc_clang_prereq (2,8) > # define isnan(x) __builtin_isnan (x) > # else > # define isnan(x) __MATH_TG ((x), __isnan, (x)) > @@ -939,7 +943,8 @@ enum > # define isinf(x) \ > (__builtin_types_compatible_p (__typeof (x), _Float128) \ > ? __isinff128 (x) : __builtin_isinf_sign (x)) > -# elif __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ > +# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ > + || __glibc_clang_prereq (3,7) > # define isinf(x) __builtin_isinf_sign (x) > # else > # define isinf(x) __MATH_TG ((x), __isinf, (x)) >
If there is no objection, I will commit this shortly. On 08/02/2019 16:56, Adhemerval Zanella wrote: > Ping. > > On 01/02/2019 10:48, Adhemerval Zanella wrote: >> This patch enable the builtin usage for clang for the C99 functions >> fpclassify, isfinite, isnormal, isnan, isinf, and sigbit. This allows >> clang optimize the calls on frontend instead of call the appropriate >> glibc symbols. >> >> Checked on aarch64-linux-gnu and x86_64-linux-gnu. I checked the supported >> version for each builtin based on released version from clang/llvm. >> >> * math/math.h (fpclassify, isfinite, isnormal, isnan): Use builtin for >> clang 2.8. >> (signbit): Use builtin for clang 3.3. >> (isinf): Use builtin for clang 3.7. >> --- >> ChangeLog | 7 +++++++ >> math/math.h | 17 +++++++++++------ >> 2 files changed, 18 insertions(+), 6 deletions(-) >> >> diff --git a/math/math.h b/math/math.h >> index ffbc24af09..d70ec3877c 100644 >> --- a/math/math.h >> +++ b/math/math.h >> @@ -874,7 +874,8 @@ enum >> the __SUPPORT_SNAN__ check may be skipped for those versions. */ >> >> /* Return number of classification appropriate for X. */ >> -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ \ >> +# if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ >> + || __glibc_clang_prereq (2,8)) \ >> && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus) >> /* The check for __cplusplus allows the use of the builtin, even >> when optimization for size is on. This is provided for >> @@ -889,7 +890,7 @@ enum >> # endif >> >> /* Return nonzero value if sign of X is negative. */ >> -# if __GNUC_PREREQ (6,0) >> +# if __GNUC_PREREQ (6,0) || __glibc_clang_prereq (3,3) >> # define signbit(x) __builtin_signbit (x) >> # elif defined __cplusplus >> /* In C++ mode, __MATH_TG cannot be used, because it relies on >> @@ -907,14 +908,16 @@ enum >> # endif >> >> /* Return nonzero value if X is not +-Inf or NaN. */ >> -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ >> +# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ >> + || __glibc_clang_prereq (2,8) >> # define isfinite(x) __builtin_isfinite (x) >> # else >> # define isfinite(x) __MATH_TG ((x), __finite, (x)) >> # endif >> >> /* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ >> -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ >> +# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ >> + || __glibc_clang_prereq (2,8) >> # define isnormal(x) __builtin_isnormal (x) >> # else >> # define isnormal(x) (fpclassify (x) == FP_NORMAL) >> @@ -922,7 +925,8 @@ enum >> >> /* Return nonzero value if X is a NaN. We could use `fpclassify' but >> we already have this functions `__isnan' and it is faster. */ >> -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ >> +# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ >> + || __glibc_clang_prereq (2,8) >> # define isnan(x) __builtin_isnan (x) >> # else >> # define isnan(x) __MATH_TG ((x), __isnan, (x)) >> @@ -939,7 +943,8 @@ enum >> # define isinf(x) \ >> (__builtin_types_compatible_p (__typeof (x), _Float128) \ >> ? __isinff128 (x) : __builtin_isinf_sign (x)) >> -# elif __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ >> +# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ >> + || __glibc_clang_prereq (3,7) >> # define isinf(x) __builtin_isinf_sign (x) >> # else >> # define isinf(x) __MATH_TG ((x), __isinf, (x)) >>
On Tue, 26 Mar 2019, Adhemerval Zanella wrote:
> If there is no objection, I will commit this shortly.
I'd like to confirm you made sure the built-ins *were type-generic* in the
relevant versions of clang (not just that they existed there - in GCC,
some of the built-ins were added first as type-specific for double, which
would have made them inappropriate to use with long double, and then later
changed to be type-generic).
--
Joseph S. Myers
joseph@codesourcery.com
On 26/03/2019 17:47, Joseph Myers wrote: > On Tue, 26 Mar 2019, Adhemerval Zanella wrote: > >> If there is no objection, I will commit this shortly. > > I'd like to confirm you made sure the built-ins *were type-generic* in the > relevant versions of clang (not just that they existed there - in GCC, > some of the built-ins were added first as type-specific for double, which > would have made them inappropriate to use with long double, and then later > changed to be type-generic). > My understanding is it only provides the C99 type-generic ones (clang does not provide __builtin_isnanf or __builtin_isnanl for instance). If I recall correctly, it has not changed over the releases, but I will double check.
diff --git a/math/math.h b/math/math.h index ffbc24af09..d70ec3877c 100644 --- a/math/math.h +++ b/math/math.h @@ -874,7 +874,8 @@ enum the __SUPPORT_SNAN__ check may be skipped for those versions. */ /* Return number of classification appropriate for X. */ -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ \ +# if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ + || __glibc_clang_prereq (2,8)) \ && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus) /* The check for __cplusplus allows the use of the builtin, even when optimization for size is on. This is provided for @@ -889,7 +890,7 @@ enum # endif /* Return nonzero value if sign of X is negative. */ -# if __GNUC_PREREQ (6,0) +# if __GNUC_PREREQ (6,0) || __glibc_clang_prereq (3,3) # define signbit(x) __builtin_signbit (x) # elif defined __cplusplus /* In C++ mode, __MATH_TG cannot be used, because it relies on @@ -907,14 +908,16 @@ enum # endif /* Return nonzero value if X is not +-Inf or NaN. */ -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ +# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ + || __glibc_clang_prereq (2,8) # define isfinite(x) __builtin_isfinite (x) # else # define isfinite(x) __MATH_TG ((x), __finite, (x)) # endif /* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ +# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ + || __glibc_clang_prereq (2,8) # define isnormal(x) __builtin_isnormal (x) # else # define isnormal(x) (fpclassify (x) == FP_NORMAL) @@ -922,7 +925,8 @@ enum /* Return nonzero value if X is a NaN. We could use `fpclassify' but we already have this functions `__isnan' and it is faster. */ -# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ +# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ + || __glibc_clang_prereq (2,8) # define isnan(x) __builtin_isnan (x) # else # define isnan(x) __MATH_TG ((x), __isnan, (x)) @@ -939,7 +943,8 @@ enum # define isinf(x) \ (__builtin_types_compatible_p (__typeof (x), _Float128) \ ? __isinff128 (x) : __builtin_isinf_sign (x)) -# elif __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__ +# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \ + || __glibc_clang_prereq (3,7) # define isinf(x) __builtin_isinf_sign (x) # else # define isinf(x) __MATH_TG ((x), __isinf, (x))