]> git.feebdaed.xyz Git - 0xmirror/glibc.git/commitdiff
math: Do not use __builtin_isgreater* and __builtin_isless* on clang
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Wed, 17 Dec 2025 17:51:47 +0000 (14:51 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 19 Dec 2025 16:23:06 +0000 (13:23 -0300)
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>
math/math.h

index 26cea186fc8de774aed5af6899634947ac8e166b..74b064d96e95fe51228826747a9d09972c4ebac7 100644 (file)
@@ -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