From f0b52f1dbd1a94896780591f0bcb68904455e8c2 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Thu, 30 May 2024 19:29:06 -0400 Subject: [PATCH] [compiler-rt] Stop using x86 built-in functions on AArch64 with GCC Previously, building `multc3.c` on A64 with GCC 7 or up but 9 and lower will attempt to reference `__builtin_copysignq`, an [x86-specific built-in function][1]: ``` $ gcc -c multc3.c In file included from fp_lib.h:24, from multc3.c:14: multc3.c: In function '__multc3': int_math.h:71:32: warning: implicit declaration of function '__builtin_copysignq'; did you mean '__builtin_copysign'? [-Wimplicit-function-declaration] #define crt_copysignf128(x, y) __builtin_copysignq((x), (y)) ^~~~~~~~~~~~~~~~~~~ ``` This is because `__has_builtin` is from GCC 10, and defined to 0 at the top of int_math.h for affected GCC versions, so the fallback definition is used. But `__builtin_copysignq` is unavailable on A64. Usages of `__builtin_fabsf128` have the same issue. Use version detection to find `__builtin_copysignf128` and `__builtin_fabsf128`. They are available since GCC 7 and [available][2] on both x86 and A64, given they are only used when `CRT_HAS_IEEE_TF`. [1]: https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html [2]: https://gcc.gnu.org/gcc-7/changes.html --- compiler-rt/lib/builtins/int_math.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/builtins/int_math.h b/compiler-rt/lib/builtins/int_math.h index 74d3e311db5e71..08bfe922ffa13b 100644 --- a/compiler-rt/lib/builtins/int_math.h +++ b/compiler-rt/lib/builtins/int_math.h @@ -65,9 +65,12 @@ #define crt_copysign(x, y) __builtin_copysign((x), (y)) #define crt_copysignf(x, y) __builtin_copysignf((x), (y)) #define crt_copysignl(x, y) __builtin_copysignl((x), (y)) -#if __has_builtin(__builtin_copysignf128) +// We define __has_builtin to always return 0 for GCC versions below 10, +// but __builtin_copysignf128 is available since version 7. +#if __has_builtin(__builtin_copysignf128) || \ + (defined(__GNUC__) && __GNUC__ >= 7) #define crt_copysignf128(x, y) __builtin_copysignf128((x), (y)) -#elif __has_builtin(__builtin_copysignq) || (defined(__GNUC__) && __GNUC__ >= 7) +#elif __has_builtin(__builtin_copysignq) #define crt_copysignf128(x, y) __builtin_copysignq((x), (y)) #endif #endif @@ -80,9 +83,11 @@ #define crt_fabs(x) __builtin_fabs((x)) #define crt_fabsf(x) __builtin_fabsf((x)) #define crt_fabsl(x) __builtin_fabsl((x)) -#if __has_builtin(__builtin_fabsf128) +// We define __has_builtin to always return 0 for GCC versions below 10, +// but __builtin_fabsf128 is available since version 7. +#if __has_builtin(__builtin_fabsf128) || (defined(__GNUC__) && __GNUC__ >= 7) #define crt_fabsf128(x) __builtin_fabsf128((x)) -#elif __has_builtin(__builtin_fabsq) || (defined(__GNUC__) && __GNUC__ >= 7) +#elif __has_builtin(__builtin_fabsq) #define crt_fabsf128(x) __builtin_fabsq((x)) #endif #endif