diff --git a/simde/simde-math.h b/simde/simde-math.h index 9685d903d..0a5a4a3fb 100644 --- a/simde/simde-math.h +++ b/simde/simde-math.h @@ -973,13 +973,18 @@ simde_math_fpclass(double v, const int imm8) { #endif #endif -#if HEDLEY_HAS_BUILTIN(__builtin_exp10) || HEDLEY_GCC_VERSION_CHECK(3,4,0) +/* __builtin_exp10 lowers to exp10() which is a GNU extension available + * only in glibc. Other libcs (musl, OpenBSD, FreeBSD, MinGW, etc.) + * lack the symbol and produce a link error. Fall back to pow(10, v). */ +#if (HEDLEY_HAS_BUILTIN(__builtin_exp10) || HEDLEY_GCC_VERSION_CHECK(3,4,0)) && \ + defined(__GLIBC__) # define simde_math_exp10(v) __builtin_exp10(v) #else # define simde_math_exp10(v) simde_math_pow(10.0, (v)) #endif -#if HEDLEY_HAS_BUILTIN(__builtin_exp10f) || HEDLEY_GCC_VERSION_CHECK(3,4,0) +#if (HEDLEY_HAS_BUILTIN(__builtin_exp10f) || HEDLEY_GCC_VERSION_CHECK(3,4,0)) && \ + defined(__GLIBC__) # define simde_math_exp10f(v) __builtin_exp10f(v) #else # define simde_math_exp10f(v) simde_math_powf(10.0f, (v)) @@ -1266,17 +1271,16 @@ simde_math_fpclass(double v, const int imm8) { #endif #if !defined(simde_math_roundeven) - /* GCC 10+ lowers __builtin_roundeven to a libm roundeven() call when - * the target has no native instruction. roundeven() is C23 and only - * available in glibc >= 2.25; other platforms (musl, OpenBSD, MinGW, - * etc.) lack the symbol and produce a link error. Clang lowers the - * builtin to an llvm.roundeven.* intrinsic which is always emitted - * inline (no libm dependency), so the GCC guard is not needed there. */ + /* __builtin_roundeven lowers to a roundeven() libm call on targets + * without a native rounding instruction (x86 without SSE4.1, + * powerpc, sparc, i386, etc.). roundeven() is C23 and only + * available in glibc >= 2.25; other libcs (musl, OpenBSD, FreeBSD, + * MinGW, etc.) lack the symbol and produce a link error. Guard for + * all compilers: non-glibc platforms use the inline fallback below. */ #if \ ((!defined(HEDLEY_EMSCRIPTEN_VERSION) || HEDLEY_EMSCRIPTEN_VERSION_CHECK(3, 1, 43)) && \ HEDLEY_HAS_BUILTIN(__builtin_roundeven) && \ - (!HEDLEY_GCC_VERSION_CHECK(10,0,0) || \ - (defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))))) + (defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)))) #define simde_math_roundeven(v) __builtin_roundeven(v) #elif defined(simde_math_round) && defined(simde_math_fabs) static HEDLEY_INLINE @@ -1295,13 +1299,12 @@ simde_math_fpclass(double v, const int imm8) { #if !defined(simde_math_roundevenf) /* Same rationale as simde_math_roundeven above; applies to the float - * variant. GCC 10+ requires glibc >= 2.25 for roundevenf(); Clang - * is always safe via llvm.roundeven.f32 inline expansion. */ + * variant. Both GCC and Clang emit a roundevenf() libm call on + * targets without a native instruction. */ #if \ ((!defined(HEDLEY_EMSCRIPTEN_VERSION) || HEDLEY_EMSCRIPTEN_VERSION_CHECK(3, 1, 43)) && \ HEDLEY_HAS_BUILTIN(__builtin_roundevenf) && \ - (!HEDLEY_GCC_VERSION_CHECK(10,0,0) || \ - (defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))))) + (defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25)))) #define simde_math_roundevenf(v) __builtin_roundevenf(v) #elif defined(simde_math_roundf) && defined(simde_math_fabsf) static HEDLEY_INLINE