mirror of
https://sourceware.org/git/glibc.git
synced 2025-12-20 01:12:17 +08:00
math: Do not use __builtin_isgreater* and __builtin_isless* on clang
clang does not check for unordered numbers with builtins for 128-bit
float types (both _Float128 on x86_64 or long double on aarch64) [1].
For instance, the code:
#ifdef __x86_64__
typedef __float128 FLOAT128_TYPE;
#elif defined (__aarch64__)
typedef long double FLOAT128_TYPE;
#endif
int foo (FLOAT128_TYPE x, FLOAT128_TYPE y)
{
return __builtin_isgreater (x, y);
}
Will issue a __gttf2 call instead of a __unordtf2 followed by the
comparison.
Using the generic implementation fixes multiple issues with math tests,
such as:
Failure: fmax (0, qNaN): Exception "Invalid operation" set
Failure: fmax (0, -qNaN): Exception "Invalid operation" set
Failure: fmax (-0, qNaN): Exception "Invalid operation" set
Failure: fmax (-0, -qNaN): Exception "Invalid operation" set
Failure: fmax (9, qNaN): Exception "Invalid operation" set
Failure: fmax (9, -qNaN): Exception "Invalid operation" set
Failure: fmax (-9, qNaN): Exception "Invalid operation" set
Failure: fmax (-9, -qNaN): Exception "Invalid operation" set
It has a small performance overhead due to the extra isunordered (which
could be omitted for float and double types). Using _Generic (similar to
how __MATH_TG) on a bivariadic function requires a lot of boilerplate
macros.
[1] https://github.com/llvm/llvm-project/issues/172499
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
This commit is contained in:
@@ -1433,7 +1433,7 @@ iszero (__T __val)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __USE_ISOC99
|
#ifdef __USE_ISOC99
|
||||||
# if __GNUC_PREREQ (3, 1)
|
# if __GNUC_PREREQ (3, 1) && !defined __clang__
|
||||||
/* ISO C99 defines some macros to compare number while taking care for
|
/* ISO C99 defines some macros to compare number while taking care for
|
||||||
unordered numbers. Many FPUs provide special instructions to support
|
unordered numbers. Many FPUs provide special instructions to support
|
||||||
these operations. Generic support in GCC for these as builtins went
|
these operations. Generic support in GCC for these as builtins went
|
||||||
|
|||||||
Reference in New Issue
Block a user