From 207069edcdc9734ac3b32c0a44d3dc80e9c380db Mon Sep 17 00:00:00 2001 From: HedgehogInTheCPP Date: Sat, 22 Aug 2026 22:14:00 +0300 Subject: [PATCH] FASTFLOAT_ASSUME and Clang related crutches cleanup. --- include/fast_float/bigint.h | 19 ++++++++---- include/fast_float/constexpr_feature_detect.h | 20 +++++++------ include/fast_float/float_common.h | 30 ++++++++++++++----- include/fast_float/parse_number.h | 6 ++-- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/include/fast_float/bigint.h b/include/fast_float/bigint.h index 69c2db6..77c26a8 100644 --- a/include/fast_float/bigint.h +++ b/include/fast_float/bigint.h @@ -618,11 +618,20 @@ struct bigint : pow5_tables<> { exp -= small_step; } if (exp != 0) { - // Work around clang bug https://godbolt.org/z/zedh7rrhc - // This is similar to https://github.com/llvm/llvm-project/issues/47746, - // except the workaround described there don't work here - FASTFLOAT_TRY(small_mul(vec, limb((static_cast(small_power_of_5[0]), - small_power_of_5[exp])))); + FASTFLOAT_TRY(small_mul( + vec, + limb( +#if defined(__clang__) + // Work around clang bug https://godbolt.org/z/zedh7rrhc + // This is similar to + // https://github.com/llvm/llvm-project/issues/47746, except + // the workaround described there don't work here + (static_cast(small_power_of_5[0]), small_power_of_5[exp]) +#else + small_power_of_5[exp] +#endif + + ))); } return true; diff --git a/include/fast_float/constexpr_feature_detect.h b/include/fast_float/constexpr_feature_detect.h index a26355f..4243a1a 100644 --- a/include/fast_float/constexpr_feature_detect.h +++ b/include/fast_float/constexpr_feature_detect.h @@ -54,7 +54,7 @@ #define FASTFLOAT_INLINE_VARIABLE static constexpr #endif -// Before C++17, constexpr variables may need an out-of-class definition. +// Before C++17 constexpr variables may need an out-of-class definition. #if __cplusplus >= 201703L || (defined(_MSC_VER) && _MSVC_LANG >= 201703L) #define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 0 #else @@ -98,13 +98,15 @@ #define FASTFLOAT_HAS_BUILTIN(x) false #endif -#if defined(FASTFLOAT_ASSUME) -// user provided solution -#elif defined(__cpp_attrubute_assume) -// For support attribute [[assume]] is declared in P1774 -#define FASTFLOAT_ASSUME(expr) [[assume(expr)]] -#else -#define FASTFLOAT_ASSUME(expr) -#endif +// #if defined(FASTFLOAT_ASSUME) +// user provided solution +// #elif defined(__cpp_attrubute_assume) +// For support attribute [[assume]] is declared in P1774 +#define FASTFLOAT_ASSUME(expr) \ + assert(expr); \ + [[assume(expr)]] +// #else +// #define FASTFLOAT_ASSUME(expr) +// #endif #endif // FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index bcf904a..7def728 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -944,8 +944,12 @@ constexpr uint16_t template <> inline constexpr std::float16_t binary_format::exact_power_of_ten(am_pow_t power) { +#if defined(__clang__) // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)powers_of_ten[0], powers_of_ten[power]; + return (void)max_mantissa[0], max_mantissa[power]; +#else + return max_mantissa[power]; +#endif } template <> @@ -989,9 +993,12 @@ inline constexpr am_mant_t binary_format::max_mantissa_fast_path(am_pow_t power) { // caller is responsible to ensure that FASTFLOAT_ASSUME(power >= 0 && power <= 4); - // +#if defined(__clang__) // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)max_mantissa[0], max_mantissa[power]; +#else + return max_mantissa[power]; +#endif } template <> @@ -1077,8 +1084,12 @@ constexpr uint16_t template <> inline constexpr std::bfloat16_t binary_format::exact_power_of_ten(am_pow_t power) { +#if defined(__clang__) // Work around clang bug https://godbolt.org/z/zedh7rrhc - return (void)powers_of_ten[0], powers_of_ten[power]; + return (void)max_mantissa[0], max_mantissa[power]; +#else + return max_mantissa[power]; +#endif } template <> @@ -1122,9 +1133,12 @@ inline constexpr am_mant_t binary_format::max_mantissa_fast_path(am_pow_t power) { // caller is responsible to ensure that FASTFLOAT_ASSUME(power >= 0 && power <= 3); - // +#if defined(__clang__) // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)max_mantissa[0], max_mantissa[power]; +#else + return max_mantissa[power]; +#endif } template <> @@ -1186,7 +1200,7 @@ template <> inline constexpr am_mant_t binary_format::max_mantissa_fast_path(am_pow_t power) { // caller is responsible to ensure that - // FASTFLOAT_ASSUME(power >= 0 && power <= 22); + FASTFLOAT_ASSUME(power >= 0 && power <= 22); #if defined(__clang__) // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)max_mantissa[0], max_mantissa[power]; @@ -1199,7 +1213,7 @@ template <> inline constexpr am_mant_t binary_format::max_mantissa_fast_path(am_pow_t power) { // caller is responsible to ensure that - // FASTFLOAT_ASSUME(power >= 0 && power <= 10); + FASTFLOAT_ASSUME(power >= 0 && power <= 10); #if defined(__clang__) // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)max_mantissa[0], max_mantissa[power]; @@ -1212,7 +1226,7 @@ template <> inline constexpr double binary_format::exact_power_of_ten(am_pow_t power) { // caller is responsible to ensure that - // FASTFLOAT_ASSUME(power >= 0 && power <= 22); + FASTFLOAT_ASSUME(power >= 0 && power <= 22); #if defined(__clang__) // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)powers_of_ten[0], powers_of_ten[power]; @@ -1225,7 +1239,7 @@ template <> inline constexpr float binary_format::exact_power_of_ten(am_pow_t power) { // caller is responsible to ensure that - // FASTFLOAT_ASSUME(power >= 0 && power <= 10); + FASTFLOAT_ASSUME(power >= 0 && power <= 10); #if defined(__clang__) // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)powers_of_ten[0], powers_of_ten[power]; diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index 7fdd655..548db8d 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -218,9 +218,11 @@ clinger_fast_path_impl(am_mant_t const mantissa, am_pow_t const exponent, // We could check it first (before the previous branch), but // there might be performance advantages at having the check // be last. + if (!is_constant_evaluated() #ifndef FASTFLOAT_ONLY_ROUNDS_TO_NEAREST_SUPPORTED - if (detail::rounds_to_nearest()) { + && detail::rounds_to_nearest() #endif + ) { // We have that fegetround() == FE_TONEAREST. // Next is Clinger's fast path. if (mantissa <= binary_format::max_mantissa_fast_path()) { @@ -263,8 +265,8 @@ clinger_fast_path_impl(am_mant_t const mantissa, am_pow_t const exponent, } #endif return true; - } #endif + } } } return false;