From a98243129530c852cbd42bffafc74ab635934d8a Mon Sep 17 00:00:00 2001 From: Tue Ly Date: Tue, 6 Jun 2023 11:50:26 -0400 Subject: [PATCH] [libc] Add platform independent floating point rounding mode checks. Many math functions need to check for floating point rounding modes to return correct values. Currently most of them use the internal implementation of `fegetround`, which is platform-dependent and blocking math functions to be enabled on platforms with unimplemented `fegetround`. In this change, we add platform independent rounding mode checks and switching math functions to use them instead. https://github.com/llvm/llvm-project/issues/63016 Reviewed By: sivachandra Differential Revision: https://reviews.llvm.org/D152280 --- libc/src/__support/CMakeLists.txt | 1 + libc/src/__support/FPUtil/CMakeLists.txt | 12 +++ libc/src/__support/FPUtil/Hypot.h | 5 +- .../__support/FPUtil/NearestIntegerOperations.h | 3 +- libc/src/__support/FPUtil/except_value_utils.h | 5 +- libc/src/__support/FPUtil/generic/CMakeLists.txt | 3 + libc/src/__support/FPUtil/generic/FMA.h | 3 +- libc/src/__support/FPUtil/generic/sqrt.h | 3 +- .../FPUtil/generic/sqrt_80_bit_long_double.h | 3 +- libc/src/__support/FPUtil/rounding_mode.h | 79 ++++++++++++++ libc/src/__support/str_to_float.h | 3 +- libc/src/math/generic/CMakeLists.txt | 10 ++ libc/src/math/generic/atanf.cpp | 5 +- libc/src/math/generic/coshf.cpp | 3 +- libc/src/math/generic/exp10f.cpp | 9 +- libc/src/math/generic/exp2f.cpp | 9 +- libc/src/math/generic/expf.cpp | 5 +- libc/src/math/generic/expm1f.cpp | 9 +- libc/src/math/generic/sincosf.cpp | 3 +- libc/src/math/generic/sinf.cpp | 3 +- libc/src/math/generic/sinhf.cpp | 5 +- libc/src/math/generic/tanhf.cpp | 3 +- libc/src/stdio/printf_core/CMakeLists.txt | 1 + libc/src/stdio/printf_core/float_dec_converter.h | 7 +- libc/src/stdio/printf_core/float_hex_converter.h | 3 +- libc/test/src/__support/FPUtil/CMakeLists.txt | 10 ++ .../src/__support/FPUtil/rounding_mode_test.cpp | 116 +++++++++++++++++++++ utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 26 +++++ 28 files changed, 312 insertions(+), 35 deletions(-) create mode 100644 libc/src/__support/FPUtil/rounding_mode.h create mode 100644 libc/test/src/__support/FPUtil/rounding_mode_test.cpp diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 676f1b98dba4..4a7b41369790 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -133,6 +133,7 @@ add_header_library( libc.src.__support.CPP.limits libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.rounding_mode libc.src.__support.builtin_wrappers libc.src.__support.common libc.src.errno.errno diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt index b772b9d47cee..3a6b6de1cfc8 100644 --- a/libc/src/__support/FPUtil/CMakeLists.txt +++ b/libc/src/__support/FPUtil/CMakeLists.txt @@ -4,6 +4,15 @@ add_header_library( FEnvImpl.h DEPENDS libc.include.fenv + libc.src.__support.macros.attributes +) + +add_header_library( + rounding_mode + HDRS + rounding_mode.h + DEPENDS + libc.include.fenv libc.include.math libc.src.__support.macros.attributes libc.src.__support.macros.properties.architectures @@ -62,6 +71,7 @@ add_header_library( DEPENDS .fp_bits .fenv_impl + .rounding_mode libc.src.__support.CPP.type_traits libc.src.__support.common libc.include.math @@ -124,6 +134,7 @@ add_header_library( DEPENDS .fp_bits .fenv_impl + .rounding_mode libc.src.__support.CPP.optional libc.src.__support.macros.optimization ) @@ -137,6 +148,7 @@ add_header_library( .basic_operations .fenv_impl .fp_bits + .rounding_mode libc.src.__support.builtin_wrappers libc.src.__support.CPP.bit libc.src.__support.CPP.type_traits diff --git a/libc/src/__support/FPUtil/Hypot.h b/libc/src/__support/FPUtil/Hypot.h index 86817b749654..61bf10bfc4f6 100644 --- a/libc/src/__support/FPUtil/Hypot.h +++ b/libc/src/__support/FPUtil/Hypot.h @@ -12,6 +12,7 @@ #include "BasicOperations.h" #include "FEnvImpl.h" #include "FPBits.h" +#include "rounding_mode.h" #include "src/__support/CPP/bit.h" #include "src/__support/CPP/type_traits.h" #include "src/__support/UInt128.h" @@ -190,7 +191,7 @@ LIBC_INLINE T hypot(T x, T y) { sum >>= 2; ++out_exp; if (out_exp >= FPBits_t::MAX_EXPONENT) { - if (int round_mode = get_round(); + if (int round_mode = quick_get_round(); round_mode == FE_TONEAREST || round_mode == FE_UPWARD) return T(FPBits_t::inf()); return T(FPBits_t(FPBits_t::MAX_NORMAL)); @@ -231,7 +232,7 @@ LIBC_INLINE T hypot(T x, T y) { y_new >>= 1; // Round to the nearest, tie to even. - int round_mode = get_round(); + int round_mode = quick_get_round(); switch (round_mode) { case FE_TONEAREST: // Round to nearest, ties to even diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h index 7081fc59057c..96007ac5b7f5 100644 --- a/libc/src/__support/FPUtil/NearestIntegerOperations.h +++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h @@ -11,6 +11,7 @@ #include "FEnvImpl.h" #include "FPBits.h" +#include "rounding_mode.h" #include "src/__support/CPP/type_traits.h" #include "src/__support/common.h" @@ -162,7 +163,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) { bool is_neg = bits.get_sign(); int exponent = bits.get_exponent(); - int rounding_mode = get_round(); + int rounding_mode = quick_get_round(); // If the exponent is greater than the most negative mantissa // exponent, then x is already an integer. diff --git a/libc/src/__support/FPUtil/except_value_utils.h b/libc/src/__support/FPUtil/except_value_utils.h index 8a5395fae12b..df1b9c74aab2 100644 --- a/libc/src/__support/FPUtil/except_value_utils.h +++ b/libc/src/__support/FPUtil/except_value_utils.h @@ -11,6 +11,7 @@ #include "FEnvImpl.h" #include "FPBits.h" +#include "rounding_mode.h" #include "src/__support/CPP/optional.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY @@ -52,7 +53,7 @@ template struct ExceptValues { for (size_t i = 0; i < N; ++i) { if (LIBC_UNLIKELY(x_bits == values[i].input)) { UIntType out_bits = values[i].rnd_towardzero_result; - switch (fputil::get_round()) { + switch (fputil::quick_get_round()) { case FE_UPWARD: out_bits += values[i].rnd_upward_offset; break; @@ -74,7 +75,7 @@ template struct ExceptValues { for (size_t i = 0; i < N; ++i) { if (LIBC_UNLIKELY(x_abs == values[i].input)) { UIntType out_bits = values[i].rnd_towardzero_result; - switch (fputil::get_round()) { + switch (fputil::quick_get_round()) { case FE_UPWARD: out_bits += sign ? values[i].rnd_downward_offset : values[i].rnd_upward_offset; diff --git a/libc/src/__support/FPUtil/generic/CMakeLists.txt b/libc/src/__support/FPUtil/generic/CMakeLists.txt index 5b028839f5bb..7f986d05aded 100644 --- a/libc/src/__support/FPUtil/generic/CMakeLists.txt +++ b/libc/src/__support/FPUtil/generic/CMakeLists.txt @@ -9,6 +9,7 @@ add_header_library( libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.platform_defs + libc.src.__support.FPUtil.rounding_mode libc.src.__support.builtin_wrappers libc.src.__support.common libc.src.__support.uint128 @@ -25,6 +26,7 @@ add_header_library( libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.float_properties libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.rounding_mode libc.src.__support.builtin_wrappers libc.src.__support.macros.optimization libc.src.__support.uint128 @@ -40,6 +42,7 @@ add_header_library( libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.float_properties libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.rounding_mode libc.src.__support.builtin_wrappers libc.src.__support.macros.optimization libc.src.math.generic.math_utils diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h index 2af91c128987..86cc40c808cd 100644 --- a/libc/src/__support/FPUtil/generic/FMA.h +++ b/libc/src/__support/FPUtil/generic/FMA.h @@ -13,6 +13,7 @@ #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/FloatProperties.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/UInt128.h" #include "src/__support/builtin_wrappers.h" #include "src/__support/macros/attributes.h" // LIBC_INLINE @@ -254,7 +255,7 @@ template <> LIBC_INLINE double fma(double x, double y, double z) { } // Finalize the result. - int round_mode = fputil::get_round(); + int round_mode = fputil::quick_get_round(); if (LIBC_UNLIKELY(r_exp >= FPBits::MAX_EXPONENT)) { if ((round_mode == FE_TOWARDZERO) || (round_mode == FE_UPWARD && prod_sign) || diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h index 1464056417d0..9e9896ed185f 100644 --- a/libc/src/__support/FPUtil/generic/sqrt.h +++ b/libc/src/__support/FPUtil/generic/sqrt.h @@ -15,6 +15,7 @@ #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PlatformDefs.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/UInt128.h" #include "src/__support/builtin_wrappers.h" #include "src/__support/common.h" @@ -150,7 +151,7 @@ LIBC_INLINE cpp::enable_if_t, T> sqrt(T x) { y = (y - ONE) | (static_cast(x_exp) << MantissaWidth::VALUE); - switch (get_round()) { + switch (quick_get_round()) { case FE_TONEAREST: // Round to nearest, ties to even if (rb && (lsb || (r != 0))) diff --git a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h index 17a1c25bc640..3712012d3be8 100644 --- a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h +++ b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h @@ -12,6 +12,7 @@ #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PlatformDefs.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/UInt128.h" #include "src/__support/builtin_wrappers.h" #include "src/__support/common.h" @@ -114,7 +115,7 @@ LIBC_INLINE long double sqrt(long double x) { y |= (static_cast(x_exp) << (MantissaWidth::VALUE + 1)); - switch (get_round()) { + switch (quick_get_round()) { case FE_TONEAREST: // Round to nearest, ties to even if (rb && (lsb || (r != 0))) diff --git a/libc/src/__support/FPUtil/rounding_mode.h b/libc/src/__support/FPUtil/rounding_mode.h new file mode 100644 index 000000000000..28e2189ccb01 --- /dev/null +++ b/libc/src/__support/FPUtil/rounding_mode.h @@ -0,0 +1,79 @@ +//===---- Free-standing function to detect rounding mode --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_ROUNDING_MODE_H +#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_ROUNDING_MODE_H + +#include "src/__support/macros/attributes.h" // LIBC_INLINE + +#include + +namespace __llvm_libc::fputil { + +// Quick free-standing test whether fegetround() == FE_UPWARD. +// Using the following observation: +// 1.0f + 2^-25 = 1.0f for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO +// = 0x1.000002f for FE_UPWARD. +LIBC_INLINE bool fenv_is_round_up() { + volatile float x = 0x1.0p-25f; + return (1.0f + x != 1.0f); +} + +// Quick free-standing test whether fegetround() == FE_DOWNWARD. +// Using the following observation: +// -1.0f - 2^-25 = -1.0f for FE_TONEAREST, FE_UPWARD, FE_TOWARDZERO +// = -0x1.000002f for FE_DOWNWARD. +LIBC_INLINE bool fenv_is_round_down() { + volatile float x = 0x1.0p-25f; + return (-1.0f - x != -1.0f); +} + +// Quick free-standing test whether fegetround() == FE_TONEAREST. +// Using the following observation: +// 1.5f + 2^-24 = 1.5f for FE_TONEAREST, FE_DOWNWARD, FE_TOWARDZERO +// = 0x1.100002p0f for FE_UPWARD, +// 1.5f - 2^-24 = 1.5f for FE_TONEAREST, FE_UPWARD +// = 0x1.0ffffep-1f for FE_DOWNWARD, FE_TOWARDZERO +LIBC_INLINE bool fenv_is_round_to_nearest() { + static volatile float x = 0x1.0p-24f; + float y = x; + return (1.5f + y == 1.5f - y); +} + +// Quick free-standing test whether fegetround() == FE_TOWARDZERO. +// Using the following observation: +// 1.0f + 2^-23 + 2^-24 = 0x1.000002p0f for FE_DOWNWARD, FE_TOWARDZERO +// = 0x1.000004p0f for FE_TONEAREST, FE_UPWARD, +// -1.0f - 2^-24 = -1.0f for FE_TONEAREST, FE_UPWARD, FE_TOWARDZERO +// = -0x1.000002p0f for FE_DOWNWARD +// So: +// (0x1.000002p0f + 2^-24) + (-1.0f - 2^-24) = 2^-23 for FE_TOWARDZERO +// = 2^-22 for FE_TONEAREST, FE_UPWARD +// = 0 for FE_DOWNWARD +LIBC_INLINE bool fenv_is_round_to_zero() { + static volatile float x = 0x1.0p-24f; + float y = x; + return ((0x1.000002p0f + y) + (-1.0f - y) == 0x1.0p-23f); +} + +// Quick free standing get rounding mode based on the above observations. +LIBC_INLINE int quick_get_round() { + static volatile float x = 0x1.0p-24f; + float y = x; + float z = (0x1.000002p0f + y) + (-1.0f - y); + + if (z == 0.0f) + return FE_DOWNWARD; + if (z == 0x1.0p-23f) + return FE_TOWARDZERO; + return (2.0f + y == 2.0f) ? FE_TONEAREST : FE_UPWARD; +} + +} // namespace __llvm_libc::fputil + +#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_ROUNDING_MODE_H diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h index b36c73fbe8ef..2ffa70f98f22 100644 --- a/libc/src/__support/str_to_float.h +++ b/libc/src/__support/str_to_float.h @@ -13,6 +13,7 @@ #include "src/__support/CPP/optional.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/UInt128.h" #include "src/__support/builtin_wrappers.h" #include "src/__support/common.h" @@ -1120,7 +1121,7 @@ LIBC_INLINE StrToNumResult strtofloatingpoint(const char *__restrict src) { RoundDirection round_direction = RoundDirection::Nearest; - switch (fputil::get_round()) { + switch (fputil::quick_get_round()) { case FE_TONEAREST: round_direction = RoundDirection::Nearest; break; diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index b2bde15b293e..fc833a8a7138 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -109,6 +109,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.fma libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization COMPILE_OPTIONS -O3 @@ -130,6 +131,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.fma libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization COMPILE_OPTIONS -O3 @@ -542,6 +544,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.nearest_integer libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization libc.include.errno libc.src.errno.errno @@ -563,6 +566,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.nearest_integer libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization libc.include.errno libc.src.errno.errno @@ -584,6 +588,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.nearest_integer libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization libc.include.errno libc.src.errno.errno @@ -606,6 +611,7 @@ add_entrypoint_object( libc.src.__support.FPUtil.multiply_add libc.src.__support.FPUtil.nearest_integer libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization libc.include.errno libc.src.errno.errno @@ -1336,6 +1342,7 @@ add_entrypoint_object( .explogxf libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization COMPILE_OPTIONS -O3 @@ -1350,6 +1357,7 @@ add_entrypoint_object( DEPENDS .explogxf libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization COMPILE_OPTIONS -O3 @@ -1364,6 +1372,7 @@ add_entrypoint_object( DEPENDS .explogxf libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization COMPILE_OPTIONS -O3 @@ -1483,6 +1492,7 @@ add_entrypoint_object( .inv_trigf_utils .math_utils libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.rounding_mode libc.src.__support.macros.optimization COMPILE_OPTIONS -O3 diff --git a/libc/src/math/generic/atanf.cpp b/libc/src/math/generic/atanf.cpp index ed7847adb15a..9b0c11996a5b 100644 --- a/libc/src/math/generic/atanf.cpp +++ b/libc/src/math/generic/atanf.cpp @@ -9,6 +9,7 @@ #include "src/math/atanf.h" #include "math_utils.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/math/generic/inv_trigf_utils.h" @@ -28,7 +29,7 @@ LLVM_LIBC_FUNCTION(float, atanf, (float x)) { } // |x| == 0.06905200332403183 if (LIBC_UNLIKELY(xbits.uintval() == 0x3d8d6b23U)) { - if (fputil::get_round() == FE_TONEAREST) { + if (fputil::fenv_is_round_to_nearest()) { // 0.06894256919622421 FPBits br(0x3d8d31c3U); br.set_sign(sign); @@ -38,7 +39,7 @@ LLVM_LIBC_FUNCTION(float, atanf, (float x)) { // |x| == 1.8670953512191772 if (LIBC_UNLIKELY(xbits.uintval() == 0x3feefcfbU)) { - int rounding_mode = fputil::get_round(); + int rounding_mode = fputil::quick_get_round(); if (sign) { if (rounding_mode == FE_DOWNWARD) { // -1.0790828466415405 diff --git a/libc/src/math/generic/coshf.cpp b/libc/src/math/generic/coshf.cpp index 1cf789a10a8c..8b30d51c69dc 100644 --- a/libc/src/math/generic/coshf.cpp +++ b/libc/src/math/generic/coshf.cpp @@ -9,6 +9,7 @@ #include "src/math/coshf.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/math/generic/explogxf.h" @@ -32,7 +33,7 @@ LLVM_LIBC_FUNCTION(float, coshf, (float x)) { if (xbits.is_inf_or_nan()) return x + FPBits::inf().get_val(); - int rounding = fputil::get_round(); + int rounding = fputil::quick_get_round(); if (LIBC_UNLIKELY(rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)) return FPBits(FPBits::MAX_NORMAL).get_val(); diff --git a/libc/src/math/generic/exp10f.cpp b/libc/src/math/generic/exp10f.cpp index 9d07f2c5261e..b0e93dd6fbca 100644 --- a/libc/src/math/generic/exp10f.cpp +++ b/libc/src/math/generic/exp10f.cpp @@ -14,6 +14,7 @@ #include "src/__support/FPUtil/PolyEval.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/FPUtil/nearest_integer.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/common.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY @@ -38,7 +39,7 @@ LLVM_LIBC_FUNCTION(float, exp10f, (float x)) { // exp(nan) = nan if (xbits.is_nan()) return x; - if (fputil::get_round() == FE_UPWARD) + if (fputil::fenv_is_round_up()) return static_cast(FPBits(FPBits::MIN_SUBNORMAL)); fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_UNDERFLOW); @@ -48,7 +49,7 @@ LLVM_LIBC_FUNCTION(float, exp10f, (float x)) { if (!xbits.get_sign() && (x_u >= 0x421a'209bU)) { // x is finite if (x_u < 0x7f80'0000U) { - int rounding = fputil::get_round(); + int rounding = fputil::quick_get_round(); if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) return static_cast(FPBits(FPBits::MAX_NORMAL)); @@ -63,7 +64,7 @@ LLVM_LIBC_FUNCTION(float, exp10f, (float x)) { // When |x| <= log10(2)*2^-6 if (LIBC_UNLIKELY(x_abs <= 0x3b9a'209bU)) { if (LIBC_UNLIKELY(x_u == 0xb25e'5bd9U)) { // x = -0x1.bcb7b2p-27f - if (fputil::get_round() == FE_TONEAREST) + if (fputil::fenv_is_round_to_nearest()) return 0x1.fffffep-1f; } // |x| < 2^-25 @@ -77,7 +78,7 @@ LLVM_LIBC_FUNCTION(float, exp10f, (float x)) { // Exceptional value. if (LIBC_UNLIKELY(x_u == 0x3d14'd956U)) { // x = 0x1.29b2acp-5f - if (fputil::get_round() == FE_UPWARD) + if (fputil::fenv_is_round_up()) return 0x1.1657c4p+0f; } diff --git a/libc/src/math/generic/exp2f.cpp b/libc/src/math/generic/exp2f.cpp index f68d553c65de..f2c005d5e00a 100644 --- a/libc/src/math/generic/exp2f.cpp +++ b/libc/src/math/generic/exp2f.cpp @@ -12,6 +12,7 @@ #include "src/__support/FPUtil/PolyEval.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/FPUtil/nearest_integer.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/common.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY @@ -44,7 +45,7 @@ LLVM_LIBC_FUNCTION(float, exp2f, (float x)) { if (!xbits.get_sign()) { // x is finite if (x_u < 0x7f80'0000U) { - int rounding = fputil::get_round(); + int rounding = fputil::quick_get_round(); if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) return static_cast(FPBits(FPBits::MAX_NORMAL)); @@ -62,7 +63,7 @@ LLVM_LIBC_FUNCTION(float, exp2f, (float x)) { // exp(nan) = nan if (xbits.is_nan()) return x; - if (fputil::get_round() == FE_UPWARD) + if (fputil::fenv_is_round_up()) return FPBits(FPBits::MIN_SUBNORMAL).get_val(); if (x != 0.0f) { fputil::set_errno_if_required(ERANGE); @@ -75,10 +76,10 @@ LLVM_LIBC_FUNCTION(float, exp2f, (float x)) { // Check exceptional values. if (LIBC_UNLIKELY((x_u & EXVAL_MASK) == EXVAL_MASK)) { if (LIBC_UNLIKELY(x_u == EXVAL1)) { // x = 0x1.853a6ep-9f - if (fputil::get_round() == FE_TONEAREST) + if (fputil::fenv_is_round_to_nearest()) return 0x1.00870ap+0f; } else if (LIBC_UNLIKELY(x_u == EXVAL2)) { // x = -0x1.e7526ep-6f - if (fputil::get_round() == FE_TONEAREST) + if (fputil::fenv_is_round_to_nearest()) return 0x1.f58d62p-1f; } } diff --git a/libc/src/math/generic/expf.cpp b/libc/src/math/generic/expf.cpp index cbee8a1ec464..2cc8406c095a 100644 --- a/libc/src/math/generic/expf.cpp +++ b/libc/src/math/generic/expf.cpp @@ -14,6 +14,7 @@ #include "src/__support/FPUtil/PolyEval.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/FPUtil/nearest_integer.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/common.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY @@ -48,7 +49,7 @@ LLVM_LIBC_FUNCTION(float, expf, (float x)) { // exp(nan) = nan if (xbits.is_nan()) return x; - if (fputil::get_round() == FE_UPWARD) + if (fputil::fenv_is_round_up()) return static_cast(FPBits(FPBits::MIN_SUBNORMAL)); fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_UNDERFLOW); @@ -58,7 +59,7 @@ LLVM_LIBC_FUNCTION(float, expf, (float x)) { if (!xbits.get_sign() && (xbits.uintval() >= 0x42b2'0000)) { // x is finite if (xbits.uintval() < 0x7f80'0000U) { - int rounding = fputil::get_round(); + int rounding = fputil::quick_get_round(); if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) return static_cast(FPBits(FPBits::MAX_NORMAL)); diff --git a/libc/src/math/generic/expm1f.cpp b/libc/src/math/generic/expm1f.cpp index 33e408cd7861..811baec0e910 100644 --- a/libc/src/math/generic/expm1f.cpp +++ b/libc/src/math/generic/expm1f.cpp @@ -15,6 +15,7 @@ #include "src/__support/FPUtil/PolyEval.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/FPUtil/nearest_integer.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/common.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA @@ -32,7 +33,7 @@ LLVM_LIBC_FUNCTION(float, expm1f, (float x)) { // Exceptional value if (LIBC_UNLIKELY(x_u == 0x3e35'bec5U)) { // x = 0x1.6b7d8ap-3f - int round_mode = fputil::get_round(); + int round_mode = fputil::quick_get_round(); if (round_mode == FE_TONEAREST || round_mode == FE_UPWARD) return 0x1.8dbe64p-3f; return 0x1.8dbe62p-3f; @@ -40,7 +41,7 @@ LLVM_LIBC_FUNCTION(float, expm1f, (float x)) { #if !defined(LIBC_TARGET_CPU_HAS_FMA) if (LIBC_UNLIKELY(x_u == 0xbdc1'c6cbU)) { // x = -0x1.838d96p-4f - int round_mode = fputil::get_round(); + int round_mode = fputil::quick_get_round(); if (round_mode == FE_TONEAREST || round_mode == FE_DOWNWARD) return -0x1.71c884p-4f; return -0x1.71c882p-4f; @@ -57,7 +58,7 @@ LLVM_LIBC_FUNCTION(float, expm1f, (float x)) { // exp(nan) = nan if (xbits.is_nan()) return x; - int round_mode = fputil::get_round(); + int round_mode = fputil::quick_get_round(); if (round_mode == FE_UPWARD || round_mode == FE_TOWARDZERO) return -0x1.ffff'fep-1f; // -1.0f + 0x1.0p-24f return -1.0f; @@ -65,7 +66,7 @@ LLVM_LIBC_FUNCTION(float, expm1f, (float x)) { // x >= 89 or nan if (xbits.uintval() >= 0x42b2'0000) { if (xbits.uintval() < 0x7f80'0000U) { - int rounding = fputil::get_round(); + int rounding = fputil::quick_get_round(); if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) return static_cast(FPBits(FPBits::MAX_NORMAL)); diff --git a/libc/src/math/generic/sincosf.cpp b/libc/src/math/generic/sincosf.cpp index 277126bdc89d..1611567eef97 100644 --- a/libc/src/math/generic/sincosf.cpp +++ b/libc/src/math/generic/sincosf.cpp @@ -11,6 +11,7 @@ #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/common.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA @@ -159,7 +160,7 @@ LLVM_LIBC_FUNCTION(void, sincosf, (float x, float *sinp, float *cosp)) { uint32_t s = EXCEPT_OUTPUTS_SIN[i][0]; // FE_TOWARDZERO uint32_t c = EXCEPT_OUTPUTS_COS[i][0]; // FE_TOWARDZERO bool x_sign = x < 0; - switch (fputil::get_round()) { + switch (fputil::quick_get_round()) { case FE_UPWARD: s += x_sign ? EXCEPT_OUTPUTS_SIN[i][2] : EXCEPT_OUTPUTS_SIN[i][1]; c += EXCEPT_OUTPUTS_COS[i][1]; diff --git a/libc/src/math/generic/sinf.cpp b/libc/src/math/generic/sinf.cpp index 697c438c2c67..01d2f70e7356 100644 --- a/libc/src/math/generic/sinf.cpp +++ b/libc/src/math/generic/sinf.cpp @@ -13,6 +13,7 @@ #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PolyEval.h" #include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/common.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA @@ -126,7 +127,7 @@ LLVM_LIBC_FUNCTION(float, sinf, (float x)) { if (LIBC_UNLIKELY(x_abs == 0x4619'9998U)) { // x = 0x1.33333p13 float r = -0x1.63f4bap-2f; - int rounding = fputil::get_round(); + int rounding = fputil::quick_get_round(); bool sign = xbits.get_sign(); if ((rounding == FE_DOWNWARD && !sign) || (rounding == FE_UPWARD && sign)) r = -0x1.63f4bcp-2f; diff --git a/libc/src/math/generic/sinhf.cpp b/libc/src/math/generic/sinhf.cpp index 92edd4ea6a98..7f4d0d6e3af2 100644 --- a/libc/src/math/generic/sinhf.cpp +++ b/libc/src/math/generic/sinhf.cpp @@ -8,6 +8,7 @@ #include "src/math/sinhf.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/math/generic/explogxf.h" @@ -33,7 +34,7 @@ LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { if (xbits.is_inf()) return x; - int rounding = fputil::get_round(); + int rounding = fputil::quick_get_round(); if (sign) { if (LIBC_UNLIKELY(rounding == FE_UPWARD || rounding == FE_TOWARDZERO)) return FPBits(FPBits::MAX_NORMAL | FPBits::FloatProp::SIGN_MASK) @@ -53,7 +54,7 @@ LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { if (LIBC_UNLIKELY(x_abs <= 0x3da0'0000U)) { // |x| = 0.0005589424981735646724700927734375 if (LIBC_UNLIKELY(x_abs == 0x3a12'85ffU)) { - if (fputil::get_round() == FE_TONEAREST) + if (fputil::fenv_is_round_to_nearest()) return x; } diff --git a/libc/src/math/generic/tanhf.cpp b/libc/src/math/generic/tanhf.cpp index 8f2ba8852e4a..eb6b50a64b01 100644 --- a/libc/src/math/generic/tanhf.cpp +++ b/libc/src/math/generic/tanhf.cpp @@ -8,6 +8,7 @@ #include "src/math/tanhf.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA #include "src/math/generic/explogxf.h" @@ -52,7 +53,7 @@ LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { } if (LIBC_UNLIKELY(xbits.bits == 0x4058'e0a3U)) { - if (fputil::get_round() == FE_DOWNWARD) + if (fputil::fenv_is_round_down()) return FPBits(0x3f7f'6ad9U).get_val(); } diff --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt index bcadc0527071..b124a11bc0a5 100644 --- a/libc/src/stdio/printf_core/CMakeLists.txt +++ b/libc/src/stdio/printf_core/CMakeLists.txt @@ -93,6 +93,7 @@ add_object_library( libc.src.__support.CPP.string_view libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.rounding_mode libc.src.__support.common libc.src.__support.libc_assert libc.src.__support.uint diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h index 8d220ceeebb0..be4b2831d806 100644 --- a/libc/src/stdio/printf_core/float_dec_converter.h +++ b/libc/src/stdio/printf_core/float_dec_converter.h @@ -13,6 +13,7 @@ #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/FloatProperties.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/UInt.h" #include "src/__support/UInt128.h" #include "src/__support/common.h" @@ -600,7 +601,7 @@ LIBC_INLINE int convert_float_decimal_typed(Writer *writer, (requiredTwos < 60 && multiple_of_power_of_2(float_bits.get_explicit_mantissa(), static_cast(requiredTwos))); - switch (fputil::get_round()) { + switch (fputil::quick_get_round()) { case FE_TONEAREST: // Round to nearest, if it's exactly halfway then round to even. if (last_digit != 5) { @@ -774,7 +775,7 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer, (requiredTwos < 60 && multiple_of_power_of_2(float_bits.get_explicit_mantissa(), static_cast(requiredTwos))); - switch (fputil::get_round()) { + switch (fputil::quick_get_round()) { case FE_TONEAREST: // Round to nearest, if it's exactly halfway then round to even. if (last_digit != 5) { @@ -1022,7 +1023,7 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer, (requiredTwos < 60 && multiple_of_power_of_2(float_bits.get_explicit_mantissa(), static_cast(requiredTwos))); - switch (fputil::get_round()) { + switch (fputil::quick_get_round()) { case FE_TONEAREST: // Round to nearest, if it's exactly halfway then round to even. if (last_digit != 5) { diff --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h index a26a3e796e4d..ae5efbabb704 100644 --- a/libc/src/stdio/printf_core/float_hex_converter.h +++ b/libc/src/stdio/printf_core/float_hex_converter.h @@ -12,6 +12,7 @@ #include "src/__support/CPP/string_view.h" #include "src/__support/FPUtil/FEnvImpl.h" #include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/rounding_mode.h" #include "src/__support/common.h" #include "src/stdio/printf_core/converter_utils.h" #include "src/stdio/printf_core/core_structs.h" @@ -113,7 +114,7 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, mantissa >>= shift_amount; - switch (fputil::get_round()) { + switch (fputil::quick_get_round()) { case FE_TONEAREST: // Round to nearest, if it's exactly halfway then round to even. if (truncated_bits > halfway_const) diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt index a28c89a87bbb..411b8281470c 100644 --- a/libc/test/src/__support/FPUtil/CMakeLists.txt +++ b/libc/test/src/__support/FPUtil/CMakeLists.txt @@ -21,3 +21,13 @@ add_libc_test( libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.fpbits_str ) + +add_fp_unittest( + rounding_mode_test + SUITE + libc-fputil-tests + SRCS + rounding_mode_test.cpp + DEPENDS + libc.src.__support.FPUtil.rounding_mode +) diff --git a/libc/test/src/__support/FPUtil/rounding_mode_test.cpp b/libc/test/src/__support/FPUtil/rounding_mode_test.cpp new file mode 100644 index 000000000000..8d3332f142cc --- /dev/null +++ b/libc/test/src/__support/FPUtil/rounding_mode_test.cpp @@ -0,0 +1,116 @@ +//===-- Unittests for the quick rounding mode checks ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/FPUtil/rounding_mode.h" +#include "test/UnitTest/Test.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +#include + +using __llvm_libc::testing::mpfr::ForceRoundingMode; +using __llvm_libc::testing::mpfr::RoundingMode; + +TEST(LlvmLibcFEnvImplTest, QuickRoundingUpTest) { + using __llvm_libc::fputil::fenv_is_round_up; + { + ForceRoundingMode __r(RoundingMode::Upward); + ASSERT_TRUE(fenv_is_round_up()); + } + { + ForceRoundingMode __r(RoundingMode::Downward); + ASSERT_FALSE(fenv_is_round_up()); + } + { + ForceRoundingMode __r(RoundingMode::Nearest); + ASSERT_FALSE(fenv_is_round_up()); + } + { + ForceRoundingMode __r(RoundingMode::TowardZero); + ASSERT_FALSE(fenv_is_round_up()); + } +} + +TEST(LlvmLibcFEnvImplTest, QuickRoundingDownTest) { + using __llvm_libc::fputil::fenv_is_round_down; + { + ForceRoundingMode __r(RoundingMode::Upward); + ASSERT_FALSE(fenv_is_round_down()); + } + { + ForceRoundingMode __r(RoundingMode::Downward); + ASSERT_TRUE(fenv_is_round_down()); + } + { + ForceRoundingMode __r(RoundingMode::Nearest); + ASSERT_FALSE(fenv_is_round_down()); + } + { + ForceRoundingMode __r(RoundingMode::TowardZero); + ASSERT_FALSE(fenv_is_round_down()); + } +} + +TEST(LlvmLibcFEnvImplTest, QuickRoundingNearestTest) { + using __llvm_libc::fputil::fenv_is_round_to_nearest; + { + ForceRoundingMode __r(RoundingMode::Upward); + ASSERT_FALSE(fenv_is_round_to_nearest()); + } + { + ForceRoundingMode __r(RoundingMode::Downward); + ASSERT_FALSE(fenv_is_round_to_nearest()); + } + { + ForceRoundingMode __r(RoundingMode::Nearest); + ASSERT_TRUE(fenv_is_round_to_nearest()); + } + { + ForceRoundingMode __r(RoundingMode::TowardZero); + ASSERT_FALSE(fenv_is_round_to_nearest()); + } +} + +TEST(LlvmLibcFEnvImplTest, QuickRoundingTowardZeroTest) { + using __llvm_libc::fputil::fenv_is_round_to_zero; + { + ForceRoundingMode __r(RoundingMode::Upward); + ASSERT_FALSE(fenv_is_round_to_zero()); + } + { + ForceRoundingMode __r(RoundingMode::Downward); + ASSERT_FALSE(fenv_is_round_to_zero()); + } + { + ForceRoundingMode __r(RoundingMode::Nearest); + ASSERT_FALSE(fenv_is_round_to_zero()); + } + { + ForceRoundingMode __r(RoundingMode::TowardZero); + ASSERT_TRUE(fenv_is_round_to_zero()); + } +} + +TEST(LlvmLibcFEnvImplTest, QuickGetRoundTest) { + using __llvm_libc::fputil::quick_get_round; + { + ForceRoundingMode __r(RoundingMode::Upward); + ASSERT_EQ(quick_get_round(), FE_UPWARD); + } + { + ForceRoundingMode __r(RoundingMode::Downward); + ASSERT_EQ(quick_get_round(), FE_DOWNWARD); + } + { + ForceRoundingMode __r(RoundingMode::Nearest); + ASSERT_EQ(quick_get_round(), FE_TONEAREST); + } + { + ForceRoundingMode __r(RoundingMode::TowardZero); + ASSERT_EQ(quick_get_round(), FE_TOWARDZERO); + } +} diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index f62e5393c6ea..d7439d423882 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -444,6 +444,7 @@ libc_support_library( ":__support_ctype_utils", ":__support_fputil_fenv_impl", ":__support_fputil_fp_bits", + ":__support_fputil_rounding_mode", ":__support_str_to_integer", ":__support_str_to_num_result", ":__support_uint128", @@ -529,6 +530,7 @@ libc_support_library( ":__support_cpp_optional", ":__support_fputil_fenv_impl", ":__support_fputil_fp_bits", + ":__support_fputil_rounding_mode", ":libc_root", ], ) @@ -552,6 +554,15 @@ libc_support_library( ) libc_support_library( + name = "__support_fputil_rounding_mode", + hdrs = ["src/__support/FPUtil/rounding_mode.h"], + deps = [ + ":__support_macros_attributes", + ":libc_root", + ], +) + +libc_support_library( name = "__support_fputil_float_properties", hdrs = ["src/__support/FPUtil/FloatProperties.h"], deps = [ @@ -604,6 +615,7 @@ libc_support_library( ":__support_fputil_basic_operations", ":__support_fputil_fenv_impl", ":__support_fputil_fp_bits", + ":__support_fputil_rounding_mode", ":__support_uint128", ":libc_root", ], @@ -635,6 +647,7 @@ libc_support_library( ":__support_cpp_type_traits", ":__support_fputil_fenv_impl", ":__support_fputil_fp_bits", + ":__support_fputil_rounding_mode", ":libc_root", ], ) @@ -686,6 +699,7 @@ libc_support_library( ":__support_fputil_fenv_impl", ":__support_fputil_fp_bits", ":__support_fputil_platform_defs", + ":__support_fputil_rounding_mode", ":__support_uint128", ":libc_root", ], @@ -714,6 +728,7 @@ libc_support_library( ":__support_fputil_fenv_impl", ":__support_fputil_float_properties", ":__support_fputil_fp_bits", + ":__support_fputil_rounding_mode", ":__support_macros_attributes", ":__support_macros_optimization", ":__support_macros_properties_cpu_features", @@ -1137,6 +1152,7 @@ libc_math_function( ":__support_fputil_multiply_add", ":__support_fputil_nearest_integer", ":__support_fputil_polyeval", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":__support_macros_properties_cpu_features", ":common_constants", @@ -1150,6 +1166,7 @@ libc_math_function( ":__support_fputil_multiply_add", ":__support_fputil_nearest_integer", ":__support_fputil_polyeval", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":common_constants", ], @@ -1162,6 +1179,7 @@ libc_math_function( ":__support_fputil_multiply_add", ":__support_fputil_nearest_integer", ":__support_fputil_polyeval", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":common_constants", ":explogxf", @@ -1175,6 +1193,7 @@ libc_math_function( ":__support_fputil_multiply_add", ":__support_fputil_nearest_integer", ":__support_fputil_polyeval", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":explogxf", ], @@ -1293,6 +1312,7 @@ libc_math_function( ":__support_fputil_multiply_add", ":__support_fputil_nearest_integer", ":__support_fputil_polyeval", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":common_constants", ":explogxf", @@ -1306,6 +1326,7 @@ libc_math_function( ":__support_fputil_multiply_add", ":__support_fputil_nearest_integer", ":__support_fputil_polyeval", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":common_constants", ":explogxf", @@ -1319,6 +1340,7 @@ libc_math_function( ":__support_fputil_multiply_add", ":__support_fputil_nearest_integer", ":__support_fputil_polyeval", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":__support_macros_properties_cpu_features", ":common_constants", @@ -1401,6 +1423,7 @@ libc_math_function( ":__support_fputil_multiply_add", ":__support_fputil_nearest_integer", ":__support_fputil_polyeval", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":inv_trigf_utils", ":math_utils", @@ -1583,6 +1606,7 @@ libc_math_function( additional_deps = [ ":__support_fputil_fma", ":__support_fputil_multiply_add", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":__support_macros_properties_cpu_features", ":sincosf_utils", @@ -1595,6 +1619,7 @@ libc_math_function( ":__support_fputil_fma", ":__support_fputil_multiply_add", ":__support_fputil_polyeval", + ":__support_fputil_rounding_mode", ":__support_macros_optimization", ":__support_macros_properties_cpu_features", ":range_reduction", @@ -2552,6 +2577,7 @@ libc_support_library( ":__support_fputil_fenv_impl", ":__support_fputil_float_properties", ":__support_fputil_fp_bits", + ":__support_fputil_rounding_mode", ":__support_integer_to_string", ":__support_libc_assert", ":__support_uint", -- 2.11.4.GIT