[libc-commits] [libc] [libc][math] Add floating-point cast independent of compiler runtime (PR #105152)
via libc-commits
libc-commits at lists.llvm.org
Tue Aug 20 10:32:45 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: OverMighty (overmighty)
<details>
<summary>Changes</summary>
Fixes build and tests with compiler-rt on x86.
---
Patch is 84.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/105152.diff
38 Files Affected:
- (modified) libc/cmake/modules/CheckCompilerFeatures.cmake (+16-3)
- (added) libc/cmake/modules/compiler_features/check_float16_conversion.cpp (+30)
- (modified) libc/src/__support/FPUtil/CMakeLists.txt (+22-3)
- (modified) libc/src/__support/FPUtil/ManipulationFunctions.h (+7-5)
- (added) libc/src/__support/FPUtil/cast.h (+65)
- (modified) libc/src/__support/FPUtil/dyadic_float.h (+119-1)
- (modified) libc/src/__support/FPUtil/except_value_utils.h (+18)
- (modified) libc/src/__support/FPUtil/generic/CMakeLists.txt (+5-3)
- (modified) libc/src/__support/FPUtil/generic/FMA.h (+3-2)
- (modified) libc/src/__support/FPUtil/generic/add_sub.h (+3-2)
- (modified) libc/src/__support/FPUtil/generic/sqrt.h (+2-1)
- (modified) libc/src/math/generic/CMakeLists.txt (+18-6)
- (modified) libc/src/math/generic/ceilf16.cpp (+2-1)
- (modified) libc/src/math/generic/exp10f16.cpp (+6-5)
- (modified) libc/src/math/generic/exp2f16.cpp (+2-1)
- (modified) libc/src/math/generic/expf16.cpp (+3-2)
- (modified) libc/src/math/generic/expm1f16.cpp (+4-3)
- (modified) libc/src/math/generic/floorf16.cpp (+2-1)
- (modified) libc/src/math/generic/rintf16.cpp (+2-1)
- (modified) libc/src/math/generic/roundevenf16.cpp (+2-1)
- (modified) libc/src/math/generic/roundf16.cpp (+2-1)
- (modified) libc/src/math/generic/truncf16.cpp (+2-1)
- (modified) libc/test/src/math/smoke/AddTest.h (+23-19)
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+15)
- (modified) libc/test/src/math/smoke/DivTest.h (+46-36)
- (modified) libc/test/src/math/smoke/FModTest.h (+32-32)
- (modified) libc/test/src/math/smoke/FmaTest.h (+23-5)
- (modified) libc/test/src/math/smoke/ModfTest.h (+1-1)
- (modified) libc/test/src/math/smoke/MulTest.h (+28-24)
- (modified) libc/test/src/math/smoke/NextTowardTest.h (+8-6)
- (modified) libc/test/src/math/smoke/SqrtTest.h (+11-5)
- (modified) libc/test/src/math/smoke/SubTest.h (+21-19)
- (modified) libc/test/src/math/smoke/exp10f16_test.cpp (+8-6)
- (modified) libc/test/src/math/smoke/exp2f16_test.cpp (+8-6)
- (modified) libc/test/src/math/smoke/expf16_test.cpp (+8-6)
- (modified) libc/test/src/math/smoke/expm1f16_test.cpp (+24-20)
- (modified) libc/utils/MPFRWrapper/CMakeLists.txt (+1)
- (modified) libc/utils/MPFRWrapper/MPFRUtils.cpp (+2-1)
``````````diff
diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake b/libc/cmake/modules/CheckCompilerFeatures.cmake
index 63145fe709dda0..862c7ecbd7fdf4 100644
--- a/libc/cmake/modules/CheckCompilerFeatures.cmake
+++ b/libc/cmake/modules/CheckCompilerFeatures.cmake
@@ -10,6 +10,7 @@ set(
"builtin_round"
"builtin_roundeven"
"float16"
+ "float16_conversion"
"float128"
"fixed_point"
)
@@ -61,15 +62,21 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES)
set(link_options "")
if(${feature} STREQUAL "fixed_point")
list(APPEND compile_options "-ffixed-point")
- elseif(${feature} MATCHES "^builtin_")
+ elseif(${feature} MATCHES "^builtin_" OR
+ ${feature} STREQUAL "float16_conversion")
set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT})
set(link_options -nostdlib)
- # The compiler might handle calls to rounding builtins by generating calls
- # to the respective libc math functions, in which case we cannot use these
+ # The compiler might handle calls to math builtins by generating calls to
+ # the respective libc math functions, in which case we cannot use these
# builtins in our implementations of these functions. We check that this is
# not the case by trying to link an executable, since linking would fail due
# to unresolved references with -nostdlib if calls to libc functions were
# generated.
+ #
+ # We also had issues with soft-float float16 conversion functions using both
+ # compiler-rt and libgcc, so we also check whether we can convert from and
+ # to float16 without calls to compiler runtime functions by trying to link
+ # an executable with -nostdlib.
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
endif()
@@ -97,6 +104,8 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES)
list(APPEND AVAILABLE_COMPILER_FEATURES ${feature})
if(${feature} STREQUAL "float16")
set(LIBC_TYPES_HAS_FLOAT16 TRUE)
+ elseif(${feature} STREQUAL "float16_conversion")
+ add_compile_definitions(__LIBC_USE_FLOAT16_CONVERSION)
elseif(${feature} STREQUAL "float128")
set(LIBC_TYPES_HAS_FLOAT128 TRUE)
elseif(${feature} STREQUAL "fixed_point")
@@ -115,6 +124,10 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES)
endif()
endforeach()
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT})
+set(link_options "")
+
message(STATUS "Compiler features available: ${AVAILABLE_COMPILER_FEATURES}")
### Compiler Feature Detection ###
diff --git a/libc/cmake/modules/compiler_features/check_float16_conversion.cpp b/libc/cmake/modules/compiler_features/check_float16_conversion.cpp
new file mode 100644
index 00000000000000..09ac8e9c8bc9d6
--- /dev/null
+++ b/libc/cmake/modules/compiler_features/check_float16_conversion.cpp
@@ -0,0 +1,30 @@
+#include "include/llvm-libc-macros/float16-macros.h"
+#include "include/llvm-libc-types/float128.h"
+
+#ifndef LIBC_TYPES_HAS_FLOAT16
+#error unsupported
+#endif
+
+_Float16 cvt_from_float(float x) { return static_cast<_Float16>(x); }
+
+_Float16 cvt_from_double(double x) { return static_cast<_Float16>(x); }
+
+_Float16 cvt_from_long_double(long double x) {
+ return static_cast<_Float16>(x);
+}
+
+#ifdef LIBC_TYPES_HAS_FLOAT128
+_Float16 cvt_from_float128(float128 x) { return static_cast<_Float16>(x); }
+#endif
+
+float cvt_to_float(_Float16 x) { return x; }
+
+double cvt_to_double(_Float16 x) { return x; }
+
+long double cvt_to_long_double(_Float16 x) { return x; }
+
+#ifdef LIBC_TYPES_HAS_FLOAT128
+float128 cvt_to_float128(_Float16 x) { return x; }
+#endif
+
+extern "C" void _start() {}
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index ea1e0e8b39d101..90901549946f42 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -97,6 +97,7 @@ add_header_library(
.rounding_mode
libc.src.__support.CPP.optional
libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.types
)
@@ -175,9 +176,13 @@ add_header_library(
.fenv_impl
.fp_bits
.multiply_add
+ .rounding_mode
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
libc.src.__support.CPP.type_traits
libc.src.__support.big_int
libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.types
)
add_header_library(
@@ -217,18 +222,32 @@ add_header_library(
HDRS
ManipulationFunctions.h
DEPENDS
+ .cast
+ .dyadic_float
.fenv_impl
.fp_bits
- .dyadic_float
.nearest_integer_operations
.normal_float
libc.hdr.math_macros
+ libc.src.errno.errno
+ libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.CPP.type_traits
- libc.src.__support.common
libc.src.__support.macros.optimization
- libc.src.errno.errno
+)
+
+add_header_library(
+ cast
+ HDRS
+ cast.h
+ DEPENDS
+ .dyadic_float
+ .fp_bits
+ libc.hdr.fenv_macros
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.macros.properties.types
)
add_subdirectory(generic)
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index a14f355789999a..66bfe2aa377f99 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -12,6 +12,7 @@
#include "FPBits.h"
#include "NearestIntegerOperations.h"
#include "NormalFloat.h"
+#include "cast.h"
#include "dyadic_float.h"
#include "rounding_mode.h"
@@ -192,7 +193,8 @@ ldexp(T x, U exp) {
// For all other values, NormalFloat to T conversion handles it the right way.
DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
normal.exponent += static_cast<int>(exp);
- return static_cast<T>(normal);
+ // TODO: Add tests for exceptions.
+ return normal.template as<T, /*ShouldRaiseExceptions=*/true>();
}
template <typename T, typename U,
@@ -207,17 +209,17 @@ LIBC_INLINE T nextafter(T from, U to) {
FPBits<U> to_bits(to);
if (to_bits.is_nan())
- return static_cast<T>(to);
+ return cast<T>(to);
// NOTE: This would work only if `U` has a greater or equal precision than
// `T`. Otherwise `from` could loose its precision and the following statement
// could incorrectly evaluate to `true`.
- if (static_cast<U>(from) == to)
- return static_cast<T>(to);
+ if (cast<U>(from) == to)
+ return cast<T>(to);
using StorageType = typename FPBits<T>::StorageType;
if (from != T(0)) {
- if ((static_cast<U>(from) < to) == (from > T(0))) {
+ if ((cast<U>(from) < to) == (from > T(0))) {
from_bits = FPBits<T>(StorageType(from_bits.uintval() + 1));
} else {
from_bits = FPBits<T>(StorageType(from_bits.uintval() - 1));
diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
new file mode 100644
index 00000000000000..126f3852137b77
--- /dev/null
+++ b/libc/src/__support/FPUtil/cast.h
@@ -0,0 +1,65 @@
+//===-- Conversion between floating-point types -----------------*- 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_CAST_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_CAST_H
+
+#include "FPBits.h"
+#include "dyadic_float.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/algorithm.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE::fputil {
+
+template <typename OutType, typename InType>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
+ cpp::is_floating_point_v<InType>,
+ OutType>
+cast(InType x) {
+#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
+ if constexpr (cpp::is_same_v<OutType, float16> ||
+ cpp::is_same_v<InType, float16>) {
+ using InFPBits = FPBits<InType>;
+ using InStorageType = typename InFPBits::StorageType;
+ using OutFPBits = FPBits<OutType>;
+ using OutStorageType = typename OutFPBits::StorageType;
+
+ InFPBits x_bits(x);
+
+ if (x_bits.is_nan()) {
+ if (x_bits.is_signaling_nan()) {
+ raise_except_if_required(FE_INVALID);
+ return OutFPBits::quiet_nan().get_val();
+ }
+
+ InStorageType x_mant = x_bits.get_mantissa();
+ if (InFPBits::FRACTION_LEN > OutFPBits::FRACTION_LEN)
+ x_mant >>= InFPBits::FRACTION_LEN - OutFPBits::FRACTION_LEN;
+ return OutFPBits::quiet_nan(x_bits.sign(),
+ static_cast<OutStorageType>(x_mant))
+ .get_val();
+ }
+
+ if (x_bits.is_inf())
+ return OutFPBits::inf(x_bits.sign()).get_val();
+
+ constexpr size_t MAX_FRACTION_LEN =
+ cpp::max(OutFPBits::FRACTION_LEN, InFPBits::FRACTION_LEN);
+ DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x);
+ return xd.template as<OutType, /*ShouldSignalExceptions=*/true>();
+ }
+#endif
+
+ return static_cast<OutType>(x);
+}
+
+} // namespace LIBC_NAMESPACE::fputil
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_CAST_H
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 86346a47b35a34..814d9423a27f87 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -11,11 +11,15 @@
#include "FEnvImpl.h"
#include "FPBits.h"
+#include "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
#include "multiply_add.h"
+#include "rounding_mode.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/big_int.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/properties/types.h"
#include <stddef.h>
@@ -33,7 +37,8 @@ namespace fputil {
// The outputs of the constructors and most functions will be normalized.
// To simplify and improve the efficiency, many functions will assume that the
// inputs are normal.
-template <size_t Bits> struct DyadicFloat {
+template <size_t Bits> class DyadicFloat {
+public:
using MantissaType = LIBC_NAMESPACE::UInt<Bits>;
Sign sign = Sign::POS;
@@ -104,6 +109,11 @@ template <size_t Bits> struct DyadicFloat {
(FPBits<T>::FRACTION_LEN < Bits),
void>>
LIBC_INLINE constexpr T as() const {
+#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
+ if constexpr (cpp::is_same_v<T, float16>)
+ return generic_as<T>();
+#endif
+
if (LIBC_UNLIKELY(mantissa.is_zero()))
return FPBits<T>::zero(sign).get_val();
@@ -249,6 +259,114 @@ template <size_t Bits> struct DyadicFloat {
return new_mant;
}
+
+private:
+ template <typename OutType>
+ LIBC_INLINE constexpr cpp::enable_if_t<
+ cpp::is_floating_point_v<OutType> &&
+ sizeof(typename FPBits<OutType>::StorageType) <= sizeof(MantissaType),
+ OutType>
+ generic_as() const {
+ using FPBits = FPBits<float16>;
+ using StorageType = typename FPBits::StorageType;
+
+ constexpr int EXTRA_FRACTION_LEN = Bits - 1 - FPBits::FRACTION_LEN;
+
+ if (mantissa == 0)
+ return FPBits::zero(sign).get_val();
+
+ int unbiased_exp = get_unbiased_exponent();
+
+ if (unbiased_exp + FPBits::EXP_BIAS >= FPBits::MAX_BIASED_EXPONENT) {
+ set_errno_if_required(ERANGE);
+ raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
+
+ switch (quick_get_round()) {
+ case FE_TONEAREST:
+ return FPBits::inf(sign).get_val();
+ case FE_TOWARDZERO:
+ return FPBits::max_normal(sign).get_val();
+ case FE_DOWNWARD:
+ if (sign.is_pos())
+ return FPBits::max_normal(Sign::POS).get_val();
+ return FPBits::inf(Sign::NEG).get_val();
+ case FE_UPWARD:
+ if (sign.is_neg())
+ return FPBits::max_normal(Sign::NEG).get_val();
+ return FPBits::inf(Sign::POS).get_val();
+ default:
+ __builtin_unreachable();
+ }
+ }
+
+ StorageType out_biased_exp = 0;
+ StorageType out_mantissa = 0;
+ bool round = false;
+ bool sticky = false;
+ bool underflow = false;
+
+ if (unbiased_exp < -FPBits::EXP_BIAS - FPBits::FRACTION_LEN) {
+ sticky = true;
+ underflow = true;
+ } else if (unbiased_exp == -FPBits::EXP_BIAS - FPBits::FRACTION_LEN) {
+ round = true;
+ MantissaType sticky_mask = (MantissaType(1) << (Bits - 1)) - 1;
+ sticky = (mantissa & sticky_mask) != 0;
+ } else {
+ int extra_fraction_len = EXTRA_FRACTION_LEN;
+
+ if (unbiased_exp < 1 - FPBits::EXP_BIAS) {
+ underflow = true;
+ extra_fraction_len += 1 - FPBits::EXP_BIAS - unbiased_exp;
+ } else {
+ out_biased_exp =
+ static_cast<StorageType>(unbiased_exp + FPBits::EXP_BIAS);
+ }
+
+ MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
+ round = (mantissa & round_mask) != 0;
+ MantissaType sticky_mask = round_mask - 1;
+ sticky = (mantissa & sticky_mask) != 0;
+
+ out_mantissa = static_cast<StorageType>(mantissa >> extra_fraction_len);
+ }
+
+ bool lsb = (out_mantissa & 1) != 0;
+
+ StorageType result =
+ FPBits::create_value(sign, out_biased_exp, out_mantissa).uintval();
+
+ switch (quick_get_round()) {
+ case FE_TONEAREST:
+ if (round && (lsb || sticky))
+ ++result;
+ break;
+ case FE_DOWNWARD:
+ if (sign.is_neg() && (round || sticky))
+ ++result;
+ break;
+ case FE_UPWARD:
+ if (sign.is_pos() && (round || sticky))
+ ++result;
+ break;
+ default:
+ break;
+ }
+
+ if (round || sticky) {
+ int excepts = FE_INEXACT;
+ if (FPBits(result).is_inf()) {
+ set_errno_if_required(ERANGE);
+ excepts |= FE_OVERFLOW;
+ } else if (underflow) {
+ set_errno_if_required(ERANGE);
+ excepts |= FE_UNDERFLOW;
+ }
+ raise_except_if_required(excepts);
+ }
+
+ return FPBits(result).get_val();
+ }
};
// Quick add - Add 2 dyadic floats with rounding toward 0 and then normalize the
diff --git a/libc/src/__support/FPUtil/except_value_utils.h b/libc/src/__support/FPUtil/except_value_utils.h
index b9f54aa24e3a22..3b453fecdec76e 100644
--- a/libc/src/__support/FPUtil/except_value_utils.h
+++ b/libc/src/__support/FPUtil/except_value_utils.h
@@ -13,8 +13,11 @@
#include "FPBits.h"
#include "rounding_mode.h"
#include "src/__support/CPP/optional.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/properties/cpu_features.h"
+#include "src/__support/macros/properties/types.h"
namespace LIBC_NAMESPACE_DECL {
@@ -113,6 +116,21 @@ template <typename T> LIBC_INLINE T round_result_slightly_up(T value_rn) {
return tmp;
}
+#if defined(LIBC_TYPES_HAS_FLOAT16) && \
+ !defined(LIBC_TARGET_CPU_HAS_FAST_FLOAT16_OPS)
+template <> LIBC_INLINE float16 round_result_slightly_down(float16 value_rn) {
+ volatile float tmp = value_rn;
+ tmp -= FPBits<float16>::min_normal().get_val();
+ return cast<float16>(tmp);
+}
+
+template <> LIBC_INLINE float16 round_result_slightly_up(float16 value_rn) {
+ volatile float tmp = value_rn;
+ tmp += FPBits<float16>::min_normal().get_val();
+ return cast<float16>(tmp);
+}
+#endif
+
} // namespace fputil
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/FPUtil/generic/CMakeLists.txt b/libc/src/__support/FPUtil/generic/CMakeLists.txt
index 43096aa529fc37..b6f58f3fab571a 100644
--- a/libc/src/__support/FPUtil/generic/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/generic/CMakeLists.txt
@@ -8,6 +8,7 @@ add_header_library(
libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
@@ -21,16 +22,17 @@ add_header_library(
FMA.h
DEPENDS
libc.hdr.fenv_macros
+ libc.src.__support.big_int
libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.CPP.type_traits
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.big_int
libc.src.__support.macros.optimization
libc.src.__support.uint128
)
@@ -60,12 +62,12 @@ add_header_library(
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
libc.src.__support.FPUtil.basic_operations
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
- libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.macros.attributes
- libc.src.__support.macros.optimization
)
add_header_library(
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index e5683c8ff61ea0..bec312e44b1b10 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -14,6 +14,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/big_int.h"
@@ -157,7 +158,7 @@ fma(InType x, InType y, InType z) {
}
if (LIBC_UNLIKELY(x == 0 || y == 0 || z == 0))
- return static_cast<OutType>(x * y + z);
+ return cast<OutType>(x * y + z);
int x_exp = 0;
int y_exp = 0;
@@ -198,7 +199,7 @@ fma(InType x, InType y, InType z) {
if (LIBC_UNLIKELY(x_exp == InFPBits::MAX_BIASED_EXPONENT ||
y_exp == InFPBits::MAX_BIASED_EXPONENT ||
z_exp == InFPBits::MAX_BIASED_EXPONENT))
- return static_cast<OutType>(x * y + z);
+ return cast<OutType>(x * y + z);
// Extract mantissa and append hidden leading bits.
InStorageType x_mant = x_bits.get_explicit_mantissa();
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 850db3f83209e6..6bc9dcd23bafad 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -17,6 +17,7 @@
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/macros/attributes.h"
@@ -106,14 +107,14 @@ add_or_sub(InType x, InType y) {
volatile InType tmp = y;
if constexpr (IsSub)
tmp = -tmp;
- return static_cast<OutType>(tmp);
+ return cast<OutType>(tmp);
}
if (y_bits.is_zero()) {
volatile InType tmp = y;
if constexpr (IsSub)
tmp = -tmp;
- return static_cast<OutType>(tmp);
+ return cast<OutType>(tmp);
}
}
diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h
index 4502cc07d32b31..01af4bb7c90092 100644
--- a/libc/src/__support/FPUtil/generic/sqrt.h
+++ b/libc/src/__support/FPUtil/generic/sqrt.h
@@ -14,6 +14,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/dyadic_float.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
@@ -96,7 +97,...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/105152
More information about the libc-commits
mailing list