From: Adhemerval Zanella Date: Wed, 17 Dec 2025 17:51:47 +0000 (-0300) Subject: math: Do not use __builtin_isgreater* and __builtin_isless* on clang X-Git-Tag: glibc-2.43~68 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42b4589f28b1aae4ddc6df33a1874fce68486647;p=thirdparty%2Fglibc.git 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 --- diff --git a/math/math.h b/math/math.h index 26cea186fc..74b064d96e 100644 --- a/math/math.h +++ b/math/math.h @@ -1433,7 +1433,7 @@ iszero (__T __val) #endif #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 unordered numbers. Many FPUs provide special instructions to support these operations. Generic support in GCC for these as builtins went