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 676f1b9..4a7b413 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 b772b9d..3a6b6de 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 86817b7..61bf10b 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 7081fc5..96007ac 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 8a5395f..df1b9c7 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 5b02883..7f986d0 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 2af91c1..86cc40c 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 1464056..9e9896e 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 17a1c25..3712012 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 0000000..28e2189 --- /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 b36c73f..2ffa70f 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 b2bde15..fc833a8 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 ed7847a..9b0c119 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 1cf789a..8b30d51 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 9d07f2c..b0e93dd 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 f68d553..f2c005d 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 cbee8a1..2cc8406 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 33e408c..811baec 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 277126b..1611567 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 697c438..01d2f70 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 92edd4e..7f4d0d6 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 8f2ba88..eb6b50a 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 bcadc05..b124a11 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 8d220ce..be4b283 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 a26a3e7..ae5efba 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 a28c89a..411b828 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 0000000..8d3332f --- /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 f62e539..d7439d4 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.7.4