From e84a1e6fe073929c6bc97bbb673ba90e7b9c79b4 Mon Sep 17 00:00:00 2001 From: Anton Shepelev Date: Thu, 18 Sep 2025 10:42:53 -0700 Subject: [PATCH 1/8] - Initial implementation of rsqrt for single precision float Some small unrelated changes to this PR: - Added extra - to the top comments to make it look nicer in libc/shared/math/rsqrtf16.h - Put rsqrtf16 inside of libc/src/__support/math/CMakeLists.txt in sorted order - Rearanged libc_math_function rsqrtf16 in Bazel to match alphabetical order --- libc/config/linux/aarch64/entrypoints.txt | 1 + libc/config/linux/riscv/entrypoints.txt | 1 + libc/config/linux/x86_64/entrypoints.txt | 1 + libc/docs/headers/math/index.rst | 2 +- libc/include/math.yaml | 6 +++ libc/shared/math.h | 2 +- libc/shared/math/rsqrtf.h | 23 ++++++++++ libc/shared/math/rsqrtf16.h | 2 +- libc/src/__support/math/CMakeLists.txt | 46 ++++++++++++------- libc/src/math/CMakeLists.txt | 1 + libc/src/math/generic/CMakeLists.txt | 11 +++++ libc/src/math/generic/rsqrtf.cpp | 15 ++++++ libc/src/math/rsqrtf.h | 20 ++++++++ libc/test/shared/CMakeLists.txt | 2 +- libc/test/shared/shared_math_test.cpp | 1 + libc/test/src/math/CMakeLists.txt | 11 +++++ libc/test/src/math/rsqrtf_test.cpp | 41 +++++++++++++++++ libc/test/src/math/smoke/CMakeLists.txt | 11 +++++ libc/test/src/math/smoke/rsqrtf_test.cpp | 42 +++++++++++++++++ .../llvm-project-overlay/libc/BUILD.bazel | 38 +++++++++++---- 20 files changed, 249 insertions(+), 28 deletions(-) create mode 100644 libc/shared/math/rsqrtf.h create mode 100644 libc/src/math/generic/rsqrtf.cpp create mode 100644 libc/src/math/rsqrtf.h create mode 100644 libc/test/src/math/rsqrtf_test.cpp create mode 100644 libc/test/src/math/smoke/rsqrtf_test.cpp diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 00c4b2ec0f828..9e04eedd16162 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -735,6 +735,7 @@ if(LIBC_TYPES_HAS_FLOAT16) libc.src.math.rintf16 libc.src.math.roundevenf16 libc.src.math.roundf16 + libc.src.math.rsqrtf libc.src.math.rsqrtf16 libc.src.math.scalblnf16 libc.src.math.scalbnf16 diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 89e3653186d13..f5742faf5355e 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -749,6 +749,7 @@ if(LIBC_TYPES_HAS_FLOAT16) libc.src.math.rintf16 libc.src.math.roundevenf16 libc.src.math.roundf16 + libc.src.math.rsqrtf libc.src.math.rsqrtf16 libc.src.math.scalblnf16 libc.src.math.scalbnf16 diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 0bb8a683c5b01..0b861c537df9e 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -784,6 +784,7 @@ if(LIBC_TYPES_HAS_FLOAT16) libc.src.math.rintf16 libc.src.math.roundevenf16 libc.src.math.roundf16 + libc.src.math.rsqrtf libc.src.math.rsqrtf16 libc.src.math.scalblnf16 libc.src.math.scalbnf16 diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst index 7d5b341ba674a..392b419b2d949 100644 --- a/libc/docs/headers/math/index.rst +++ b/libc/docs/headers/math/index.rst @@ -343,7 +343,7 @@ Higher Math Functions +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ | rootn | | | | | | | 7.12.7.8 | F.10.4.8 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ -| rsqrt | | | | |check| | | | 7.12.7.9 | F.10.4.9 | +| rsqrt | |check| | | | |check| | | | 7.12.7.9 | F.10.4.9 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ | sin | |check| | |check| | | |check| | | | 7.12.4.6 | F.10.1.6 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+ diff --git a/libc/include/math.yaml b/libc/include/math.yaml index 6c800a0e2aa28..afd3ae33305c1 100644 --- a/libc/include/math.yaml +++ b/libc/include/math.yaml @@ -2349,6 +2349,12 @@ functions: return_type: long double arguments: - type: long double + - name: rsqrtf + standards: + - stdc + return_type: float + arguments: + - type: float - name: rsqrtf16 standards: - stdc diff --git a/libc/shared/math.h b/libc/shared/math.h index 4f20095912bf1..abcea786a28b5 100644 --- a/libc/shared/math.h +++ b/libc/shared/math.h @@ -52,7 +52,7 @@ #include "math/ldexpf.h" #include "math/ldexpf128.h" #include "math/ldexpf16.h" - +#include "math/rsqrtf.h" #include "math/rsqrtf16.h" #endif // LLVM_LIBC_SHARED_MATH_H diff --git a/libc/shared/math/rsqrtf.h b/libc/shared/math/rsqrtf.h new file mode 100644 index 0000000000000..32d0a61f7c21b --- /dev/null +++ b/libc/shared/math/rsqrtf.h @@ -0,0 +1,23 @@ +//===-- Shared rsqrtf function ----------------------------------*- 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_SHARED_MATH_RSQRTF_H +#define LLVM_LIBC_SHARED_MATH_RSQRTF_H + +#include "shared/libc_common.h" +#include "src/__support/math/rsqrtf.h" + +namespace LIBC_NAMESPACE_DECL { +namespace shared { + +using math::rsqrtf; + +} // namespace shared +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SHARED_MATH_RSQRTF_H diff --git a/libc/shared/math/rsqrtf16.h b/libc/shared/math/rsqrtf16.h index 54c7499214636..8dbf065802f49 100644 --- a/libc/shared/math/rsqrtf16.h +++ b/libc/shared/math/rsqrtf16.h @@ -1,4 +1,4 @@ -//===-- Shared rsqrtf16 function -------------------------------*- C++ -*-===// +//===-- Shared rsqrtf16 function --------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt index ed5f314b0a9b5..26ad5a1d8901a 100644 --- a/libc/src/__support/math/CMakeLists.txt +++ b/libc/src/__support/math/CMakeLists.txt @@ -109,22 +109,6 @@ add_header_library( libc.src.__support.macros.properties.types ) - -add_header_library( - rsqrtf16 - HDRS - rsqrtf16.h - DEPENDS - libc.src.__support.FPUtil.cast - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.multiply_add - libc.src.__support.FPUtil.polyeval - libc.src.__support.FPUtil.manipulation_functions - libc.src.__support.macros.optimization - libc.src.__support.macros.properties.types -) - add_header_library( asin_utils HDRS @@ -775,6 +759,36 @@ add_header_library( libc.src.__support.common ) +add_header_library( + rsqrtf16 + HDRS + rsqrtf16.h + DEPENDS + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.optimization + libc.src.__support.macros.properties.types +) + +add_header_library( + rsqrtf + HDRS + rsqrtf.h + DEPENDS + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.multiply_add + libc.src.__support.FPUtil.polyeval + libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.macros.optimization + libc.src.__support.macros.properties.types +) + add_header_library( sincos_eval HDRS diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index a6f400c873b7e..271c1c0ae1045 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -516,6 +516,7 @@ add_math_entrypoint_object(roundevenf16) add_math_entrypoint_object(roundevenf128) add_math_entrypoint_object(roundevenbf16) +add_math_entrypoint_object(rsqrtf) add_math_entrypoint_object(rsqrtf16) add_math_entrypoint_object(scalbln) diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index ca7baeccae01a..2d92d7342ec96 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -988,6 +988,17 @@ add_entrypoint_object( ROUND_OPT ) +add_entrypoint_object( + rsqrtf + SRCS + rsqrtf.cpp + HDRS + ../rsqrtf.h + DEPENDS + libc.src.__support.math.rsqrtf + libc.src.errno.errno +) + add_entrypoint_object( rsqrtf16 SRCS diff --git a/libc/src/math/generic/rsqrtf.cpp b/libc/src/math/generic/rsqrtf.cpp new file mode 100644 index 0000000000000..1c37979b35ed5 --- /dev/null +++ b/libc/src/math/generic/rsqrtf.cpp @@ -0,0 +1,15 @@ +//===-- Single-precision rsqrt function -----------------------------------===// +// +// 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/math/rsqrtf.h" +#include "src/__support/math/rsqrtf.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(float, rsqrtf, (float x)) { return math::rsqrtf(x); } +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/rsqrtf.h b/libc/src/math/rsqrtf.h new file mode 100644 index 0000000000000..bc559043be828 --- /dev/null +++ b/libc/src/math/rsqrtf.h @@ -0,0 +1,20 @@ +//===-- Implementation header for rsqrtf ------------------------*- 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_MATH_RSQRTF_H +#define LLVM_LIBC_SRC_MATH_RSQRTF_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +float rsqrtf(float x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_RSQRTF_H diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt index 495d6f0a81a4c..0fa89e3ae6b62 100644 --- a/libc/test/shared/CMakeLists.txt +++ b/libc/test/shared/CMakeLists.txt @@ -48,6 +48,6 @@ add_fp_unittest( libc.src.__support.math.ldexpf libc.src.__support.math.ldexpf128 libc.src.__support.math.ldexpf16 + libc.src.__support.math.rsqrtf libc.src.__support.math.rsqrtf16 - ) diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp index aa459f88c29f5..46bd112549cbd 100644 --- a/libc/test/shared/shared_math_test.cpp +++ b/libc/test/shared/shared_math_test.cpp @@ -67,6 +67,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat) { ASSERT_FP_EQ(float(8 << 5), LIBC_NAMESPACE::shared::ldexpf(8.0f, 5)); ASSERT_FP_EQ(float(-1 * (8 << 5)), LIBC_NAMESPACE::shared::ldexpf(-8.0f, 5)); + EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::rsqrtf(1.0f)); } TEST(LlvmLibcSharedMathTest, AllDouble) { diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt index 9d644703a61ae..f728eb83ebcf4 100644 --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -1678,6 +1678,17 @@ add_fp_unittest( libc.src.math.sqrtl ) +add_fp_unittest( + rsqrtf_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + rsqrtf_test.cpp + DEPENDS + libc.src.math.rsqrtf +) + add_fp_unittest( rsqrtf16_test NEED_MPFR diff --git a/libc/test/src/math/rsqrtf_test.cpp b/libc/test/src/math/rsqrtf_test.cpp new file mode 100644 index 0000000000000..cedafb63a31de --- /dev/null +++ b/libc/test/src/math/rsqrtf_test.cpp @@ -0,0 +1,41 @@ +//===-- Exhaustive test for rsqrtf ----------------------------------------===// +// +// 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/math/rsqrtf.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +using LlvmLibcRsqrtfTest = LIBC_NAMESPACE::testing::FPTest; + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +// Range: [0, Inf] +static constexpr uint32_t POS_START = 0x00000000u; +static constexpr uint32_t POS_STOP = 0x7F800000u; + +// Range: [-Inf, 0) +// rsqrt(-0.0) is -inf, not the same for mpfr. +static constexpr uint32_t NEG_START = 0x80000001u; +static constexpr uint32_t NEG_STOP = 0xFF800000u; + +TEST_F(LlvmLibcRsqrtfTest, PositiveRange) { + for (uint32_t v = POS_START; v <= POS_STOP; ++v) { + float x = FPBits(v).get_val(); + EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, + LIBC_NAMESPACE::rsqrtf(x), 0.5); + } +} + +TEST_F(LlvmLibcRsqrtfTest, NegativeRange) { + for (uint32_t v = NEG_START; v <= NEG_STOP; ++v) { + float x = FPBits(v).get_val(); + EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, + LIBC_NAMESPACE::rsqrtf(x), 0.5); + } +} diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index eadd5f0970722..644fa90a412fa 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -3502,6 +3502,17 @@ add_fp_unittest( libc.src.math.sqrtl ) +add_fp_unittest( + rsqrtf_test + SUITE + libc-math-smoke-tests + SRCS + rsqrtf_test.cpp + DEPENDS + libc.src.math.rsqrtf + libc.hdr.errno_macros +) + add_fp_unittest( rsqrtf16_test SUITE diff --git a/libc/test/src/math/smoke/rsqrtf_test.cpp b/libc/test/src/math/smoke/rsqrtf_test.cpp new file mode 100644 index 0000000000000..9ffde79e5e9a7 --- /dev/null +++ b/libc/test/src/math/smoke/rsqrtf_test.cpp @@ -0,0 +1,42 @@ +//===-- Unittests for rsqrtf --------------------------------------------===// +// +// 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 "hdr/errno_macros.h" +#include "src/math/rsqrtf.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" + +using LlvmLibcRsqrtfTest = LIBC_NAMESPACE::testing::FPTest; + +TEST_F(LlvmLibcRsqrtfTest, SpecialNumbers) { + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::rsqrtf(aNaN)); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::rsqrtf(sNaN), FE_INVALID); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ(inf, LIBC_NAMESPACE::rsqrtf(zero)); + EXPECT_MATH_ERRNO(ERANGE); + + EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::rsqrtf(neg_zero)); + EXPECT_MATH_ERRNO(ERANGE); + + EXPECT_FP_EQ( + 1.0f, + LIBC_NAMESPACE::rsqrtf(1.0f)); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ(zero, LIBC_NAMESPACE::rsqrtf(inf)); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::rsqrtf(neg_inf)); + EXPECT_MATH_ERRNO(EDOM); + + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::rsqrtf(-2.0f)); + EXPECT_MATH_ERRNO(EDOM); +} diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 921163a413067..87ad0926bfee6 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -2296,6 +2296,20 @@ libc_support_library( ], ) +libc_support_library( + name = "__support_math_rsqrtf", + hdrs = ["src/__support/math/rsqrtf.h"], + deps = [ + ":__support_fputil_fenv_impl", + ":__support_fputil_fp_bits", + ":__support_fputil_manipulation_functions", + ":__support_fputil_multiply_add", + ":__support_fputil_polyeval", + ":__support_macros_optimization", + ":__support_macros_properties_types", + ], +) + libc_support_library( name = "__support_math_rsqrtf16", hdrs = ["src/__support/math/rsqrtf16.h"], @@ -3259,14 +3273,6 @@ libc_math_function( ], ) -libc_math_function( - name = "rsqrtf16", - additional_deps = [ - ":__support_math_rsqrtf16", - ":errno", - ], -) - libc_math_function( name = "acoshf16", additional_deps = [ @@ -4497,6 +4503,22 @@ libc_math_function(name = "roundevenf128") libc_math_function(name = "roundevenf16") +libc_math_function( + name = "rsqrtf", + additional_deps = [ + ":__support_math_rsqrtf", + ":errno", + ], +) + +libc_math_function( + name = "rsqrtf16", + additional_deps = [ + ":__support_math_rsqrtf16", + ":errno", + ], +) + libc_math_function(name = "scalbln") libc_math_function(name = "scalblnf") From 5b8b21a3364e121a37c7053818d574639e296d36 Mon Sep 17 00:00:00 2001 From: Anton Shepelev Date: Thu, 18 Sep 2025 11:03:41 -0700 Subject: [PATCH 2/8] - clang-formatted the files - added missing header --- libc/src/__support/math/rsqrtf.h | 81 ++++++++++++++++++++++++ libc/test/src/math/rsqrtf_test.cpp | 2 +- libc/test/src/math/smoke/rsqrtf_test.cpp | 4 +- 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 libc/src/__support/math/rsqrtf.h diff --git a/libc/src/__support/math/rsqrtf.h b/libc/src/__support/math/rsqrtf.h new file mode 100644 index 0000000000000..d31d277be68db --- /dev/null +++ b/libc/src/__support/math/rsqrtf.h @@ -0,0 +1,81 @@ +//===-- Implementation header for rsqrtf ----------------------*- 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_MATH_RSQRTF_H +#define LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF_H + +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/ManipulationFunctions.h" +#include "src/__support/FPUtil/cast.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/FPUtil/sqrt.h" +#include "src/__support/macros/optimization.h" + +namespace LIBC_NAMESPACE_DECL { +namespace math { + +LIBC_INLINE static constexpr float rsqrtf(float x) { + using FPBits = fputil::FPBits; + FPBits xbits(x); + + uint32_t x_u = xbits.uintval(); + uint32_t x_abs = x_u & 0x7fff'ffffU; + + constexpr uint32_t INF_BIT = FPBits::inf().uintval(); + + // x is 0, inf/nan, or negative. + if (LIBC_UNLIKELY(x_u == 0 || x_u >= INF_BIT)) { + // x is NaN + if (x_abs > INF_BIT) { + if (xbits.is_signaling_nan()) { + fputil::raise_except_if_required(FE_INVALID); + return FPBits::quiet_nan().get_val(); + } + return x; + } + + // |x| = 0 + if (x_abs == 0) { + fputil::raise_except_if_required(FE_DIVBYZERO); + fputil::set_errno_if_required(ERANGE); + return FPBits::inf(xbits.sign()).get_val(); + } + + // -inf <= x < 0 + if (x_u > 0x7fff'ffffU) { + fputil::raise_except_if_required(FE_INVALID); + fputil::set_errno_if_required(EDOM); + return FPBits::quiet_nan().get_val(); + } + + // x = +inf => rsqrt(x) = 0 + return FPBits::zero().get_val(); + } + + // TODO: add integer based implementation when LIBC_TARGET_CPU_HAS_FPU_FLOAT + // is not defined + double result = 1.0f / fputil::sqrt(fputil::cast(x)); + + // Targeted post-corrections to ensure correct rounding in half for specific + // mantissa patterns + /* + const uint32_t half_mantissa = x_abs & 0x3ff; + if (LIBC_UNLIKELY(half_mantissa == 0x011F)) { + result = fputil::multiply_add(result, 0x1.0p-21f, result); + } else if (LIBC_UNLIKELY(half_mantissa == 0x0313)) { + result = fputil::multiply_add(result, -0x1.0p-21f, result); + }*/ + + return fputil::cast(result); +} + +} // namespace math +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF_H diff --git a/libc/test/src/math/rsqrtf_test.cpp b/libc/test/src/math/rsqrtf_test.cpp index cedafb63a31de..3287dc8b5d0d5 100644 --- a/libc/test/src/math/rsqrtf_test.cpp +++ b/libc/test/src/math/rsqrtf_test.cpp @@ -16,7 +16,7 @@ using LlvmLibcRsqrtfTest = LIBC_NAMESPACE::testing::FPTest; namespace mpfr = LIBC_NAMESPACE::testing::mpfr; // Range: [0, Inf] -static constexpr uint32_t POS_START = 0x00000000u; +static constexpr uint32_t POS_START = 0x00000000u; static constexpr uint32_t POS_STOP = 0x7F800000u; // Range: [-Inf, 0) diff --git a/libc/test/src/math/smoke/rsqrtf_test.cpp b/libc/test/src/math/smoke/rsqrtf_test.cpp index 9ffde79e5e9a7..02f67c4378197 100644 --- a/libc/test/src/math/smoke/rsqrtf_test.cpp +++ b/libc/test/src/math/smoke/rsqrtf_test.cpp @@ -26,9 +26,7 @@ TEST_F(LlvmLibcRsqrtfTest, SpecialNumbers) { EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::rsqrtf(neg_zero)); EXPECT_MATH_ERRNO(ERANGE); - EXPECT_FP_EQ( - 1.0f, - LIBC_NAMESPACE::rsqrtf(1.0f)); + EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::rsqrtf(1.0f)); EXPECT_MATH_ERRNO(0); EXPECT_FP_EQ(zero, LIBC_NAMESPACE::rsqrtf(inf)); From 26674a6a2d7b4980795ba9837ce80c3596de89bc Mon Sep 17 00:00:00 2001 From: Anton Shepelev Date: Fri, 19 Sep 2025 11:22:58 -0700 Subject: [PATCH 3/8] - Created exhaustive test for rsqrt in libc/test/src/math/exhaustive/ - Created unit test template for rsqrt functions that can be called in the future by other precision functions - Changed range of values for unit-test to match the libc/test/src/math/SqrtTest.h - Changed the comments in rsqrtf.h, removed unnecessary code in the comments --- libc/src/__support/math/rsqrtf.h | 14 +--- libc/test/src/math/RsqrtTest.h | 74 +++++++++++++++++++ libc/test/src/math/exhaustive/CMakeLists.txt | 16 ++++ libc/test/src/math/exhaustive/rsqrtf_test.cpp | 27 +++++++ libc/test/src/math/rsqrtf_test.cpp | 37 +--------- 5 files changed, 123 insertions(+), 45 deletions(-) create mode 100644 libc/test/src/math/RsqrtTest.h create mode 100644 libc/test/src/math/exhaustive/rsqrtf_test.cpp diff --git a/libc/src/__support/math/rsqrtf.h b/libc/src/__support/math/rsqrtf.h index d31d277be68db..ae3cf26317dc0 100644 --- a/libc/src/__support/math/rsqrtf.h +++ b/libc/src/__support/math/rsqrtf.h @@ -58,20 +58,10 @@ LIBC_INLINE static constexpr float rsqrtf(float x) { return FPBits::zero().get_val(); } - // TODO: add integer based implementation when LIBC_TARGET_CPU_HAS_FPU_FLOAT - // is not defined + // TODO: add float based approximation when + // LIBC_TARGET_CPU_HAS_FPU_DOUBLE is not defined double result = 1.0f / fputil::sqrt(fputil::cast(x)); - // Targeted post-corrections to ensure correct rounding in half for specific - // mantissa patterns - /* - const uint32_t half_mantissa = x_abs & 0x3ff; - if (LIBC_UNLIKELY(half_mantissa == 0x011F)) { - result = fputil::multiply_add(result, 0x1.0p-21f, result); - } else if (LIBC_UNLIKELY(half_mantissa == 0x0313)) { - result = fputil::multiply_add(result, -0x1.0p-21f, result); - }*/ - return fputil::cast(result); } diff --git a/libc/test/src/math/RsqrtTest.h b/libc/test/src/math/RsqrtTest.h new file mode 100644 index 0000000000000..8cabc14fd2d28 --- /dev/null +++ b/libc/test/src/math/RsqrtTest.h @@ -0,0 +1,74 @@ +//===-- Utility class to test rsqrt -----------------------------*- 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_TEST_SRC_MATH_RSQRTTEST_H +#define LLVM_LIBC_TEST_SRC_MATH_RSQRTTEST_H + +#include "test/UnitTest/FEnvSafeTest.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +template +class RsqrtTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { + + DECLARE_SPECIAL_CONSTANTS(InType) + + static constexpr StorageType HIDDEN_BIT = + StorageType(1) << LIBC_NAMESPACE::fputil::FPBits::FRACTION_LEN; + +public: + using RsqrtFunc = OutType (*)(InType); + + // Subnormal inputs: probe both power-of-two mantissas and an even sampling + // across the subnormal range. + void test_denormal_values(RsqrtFunc func) { + // Powers of two in the subnormal mantissa space. + for (StorageType mant = 1; mant < HIDDEN_BIT; mant <<= 1) { + FPBits denormal(zero); + denormal.set_mantissa(mant); + InType x = denormal.get_val(); + ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, func(x), 0.5); + } + + // Even sampling across all subnormals. + constexpr StorageType COUNT = 200'001; + constexpr StorageType STEP = HIDDEN_BIT / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + InType x = FPBits(i).get_val(); + ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, func(x), 0.5); + } + } + + // Positive normal range sampling: skip NaNs and negative values. + void test_normal_range(RsqrtFunc func) { + constexpr StorageType COUNT = 200'001; + constexpr StorageType STEP = STORAGE_MAX / COUNT; + for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { + FPBits x_bits(v); + InType x = x_bits.get_val(); + if (x_bits.is_nan() || (x < static_cast(0))) + continue; + ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, func(x), 0.5); + } + } +}; + +#define LIST_RSQRT_TESTS(T, func) \ + using LlvmLibcRsqrtTest = RsqrtTest; \ + TEST_F(LlvmLibcRsqrtTest, DenormalValues) { test_denormal_values(&func); } \ + TEST_F(LlvmLibcRsqrtTest, NormalRange) { test_normal_range(&func); } + +#define LIST_NARROWING_RSQRT_TESTS(OutType, InType, func) \ + using LlvmLibcRsqrtTest = RsqrtTest; \ + TEST_F(LlvmLibcRsqrtTest, DenormalValues) { test_denormal_values(&func); } \ + TEST_F(LlvmLibcRsqrtTest, NormalRange) { test_normal_range(&func); } + +#endif // LLVM_LIBC_TEST_SRC_MATH_RSQRTTEST_H diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt index 07c36f424a0c3..c73a870fc0c09 100644 --- a/libc/test/src/math/exhaustive/CMakeLists.txt +++ b/libc/test/src/math/exhaustive/CMakeLists.txt @@ -26,6 +26,22 @@ add_fp_unittest( -lpthread ) +add_fp_unittest( + rsqrtf_test + NO_RUN_POSTBUILD + NEED_MPFR + SUITE + libc_math_exhaustive_tests + SRCS + rsqrtf_test.cpp + DEPENDS + .exhaustive_test + libc.src.math.rsqrtf + libc.src.__support.FPUtil.fp_bits + LINK_LIBRARIES + -lpthread +) + add_fp_unittest( sinf_test NO_RUN_POSTBUILD diff --git a/libc/test/src/math/exhaustive/rsqrtf_test.cpp b/libc/test/src/math/exhaustive/rsqrtf_test.cpp new file mode 100644 index 0000000000000..803c9b4820fc2 --- /dev/null +++ b/libc/test/src/math/exhaustive/rsqrtf_test.cpp @@ -0,0 +1,27 @@ +//===-- Exhaustive test for rsqrtf ----------------------------------------===// +// +// 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 "exhaustive_test.h" +#include "src/math/rsqrtf.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +using LlvmLibcRsqrtfTest = LIBC_NAMESPACE::testing::FPTest; + +using LlvmLibcRsqrtfExhaustiveTest = + LlvmLibcUnaryOpExhaustiveMathTest; + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +// Range: [0, Inf] +static constexpr uint32_t POS_START = 0x0000'0000U; +static constexpr uint32_t POS_STOP = 0x7f80'0000U; + +TEST_F(LlvmLibcRsqrtfExhaustiveTest, PositiveRange) { + test_full_range_all_roundings(POS_START, POS_STOP); +} diff --git a/libc/test/src/math/rsqrtf_test.cpp b/libc/test/src/math/rsqrtf_test.cpp index 3287dc8b5d0d5..4e476c0be8d41 100644 --- a/libc/test/src/math/rsqrtf_test.cpp +++ b/libc/test/src/math/rsqrtf_test.cpp @@ -1,41 +1,12 @@ -//===-- Exhaustive test for rsqrtf ----------------------------------------===// -// +//===-- Unittests for rsqrtf ----------------------------------------------===// // 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/math/rsqrtf.h" -#include "test/UnitTest/FPMatcher.h" -#include "test/UnitTest/Test.h" -#include "utils/MPFRWrapper/MPFRUtils.h" - -using LlvmLibcRsqrtfTest = LIBC_NAMESPACE::testing::FPTest; - -namespace mpfr = LIBC_NAMESPACE::testing::mpfr; +#include "RsqrtTest.h" -// Range: [0, Inf] -static constexpr uint32_t POS_START = 0x00000000u; -static constexpr uint32_t POS_STOP = 0x7F800000u; - -// Range: [-Inf, 0) -// rsqrt(-0.0) is -inf, not the same for mpfr. -static constexpr uint32_t NEG_START = 0x80000001u; -static constexpr uint32_t NEG_STOP = 0xFF800000u; - -TEST_F(LlvmLibcRsqrtfTest, PositiveRange) { - for (uint32_t v = POS_START; v <= POS_STOP; ++v) { - float x = FPBits(v).get_val(); - EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, - LIBC_NAMESPACE::rsqrtf(x), 0.5); - } -} +#include "src/math/rsqrtf.h" -TEST_F(LlvmLibcRsqrtfTest, NegativeRange) { - for (uint32_t v = NEG_START; v <= NEG_STOP; ++v) { - float x = FPBits(v).get_val(); - EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, - LIBC_NAMESPACE::rsqrtf(x), 0.5); - } -} +LIST_RSQRT_TESTS(float, LIBC_NAMESPACE::rsqrtf) From 0d8e57a9cdc07a920e65a78e69e0211e3e9d85f1 Mon Sep 17 00:00:00 2001 From: Anton Shepelev Date: Fri, 19 Sep 2025 12:22:09 -0700 Subject: [PATCH 4/8] - Added comments to RsqrtTest.h template, to clarify use case --- libc/test/src/math/RsqrtTest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/test/src/math/RsqrtTest.h b/libc/test/src/math/RsqrtTest.h index 8cabc14fd2d28..14cb708176237 100644 --- a/libc/test/src/math/RsqrtTest.h +++ b/libc/test/src/math/RsqrtTest.h @@ -1,4 +1,4 @@ -//===-- Utility class to test rsqrt -----------------------------*- C++ -*-===// +//===-- Utility class to test rsqrt[f|l] ------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. From 1cc47f3078dc9270f40d75fac44ec423b4a32a5c Mon Sep 17 00:00:00 2001 From: Anton Shepelev Date: Wed, 24 Sep 2025 13:44:51 -0700 Subject: [PATCH 5/8] Addressed the comments, fixed include in rsqrtf16_test.cpp and cmake to match rsqrtf_test.cpp --- libc/src/__support/math/CMakeLists.txt | 20 +++++++++---------- libc/src/__support/math/rsqrtf.h | 20 +++++++++---------- libc/src/math/generic/CMakeLists.txt | 1 - libc/src/math/generic/rsqrtf.cpp | 1 + libc/test/src/math/RsqrtTest.h | 2 +- libc/test/src/math/exhaustive/CMakeLists.txt | 1 - libc/test/src/math/smoke/CMakeLists.txt | 8 +++++--- libc/test/src/math/smoke/rsqrtf16_test.cpp | 3 ++- libc/test/src/math/smoke/rsqrtf_test.cpp | 3 ++- .../llvm-project-overlay/libc/BUILD.bazel | 14 ++++++------- 10 files changed, 36 insertions(+), 37 deletions(-) diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt index 26ad5a1d8901a..7fd91e116ff0c 100644 --- a/libc/src/__support/math/CMakeLists.txt +++ b/libc/src/__support/math/CMakeLists.txt @@ -760,24 +760,22 @@ add_header_library( ) add_header_library( - rsqrtf16 + rsqrtf HDRS - rsqrtf16.h + rsqrtf.h DEPENDS - libc.src.__support.FPUtil.cast - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.multiply_add - libc.src.__support.FPUtil.polyeval - libc.src.__support.FPUtil.manipulation_functions + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits libc.src.__support.macros.optimization - libc.src.__support.macros.properties.types ) add_header_library( - rsqrtf + rsqrtf16 HDRS - rsqrtf.h + rsqrtf16.h DEPENDS libc.src.__support.FPUtil.cast libc.src.__support.FPUtil.fenv_impl diff --git a/libc/src/__support/math/rsqrtf.h b/libc/src/__support/math/rsqrtf.h index ae3cf26317dc0..2b2531f9fbc0f 100644 --- a/libc/src/__support/math/rsqrtf.h +++ b/libc/src/__support/math/rsqrtf.h @@ -1,4 +1,4 @@ -//===-- Implementation header for rsqrtf ----------------------*- C++ -*-===// +//===-- Implementation header for rsqrtf ------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,11 +9,11 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF_H #define LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF_H -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/ManipulationFunctions.h" -#include "src/__support/FPUtil/cast.h" -#include "src/__support/FPUtil/multiply_add.h" +#include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/sqrt.h" #include "src/__support/macros/optimization.h" @@ -27,12 +27,12 @@ LIBC_INLINE static constexpr float rsqrtf(float x) { uint32_t x_u = xbits.uintval(); uint32_t x_abs = x_u & 0x7fff'ffffU; - constexpr uint32_t INF_BIT = FPBits::inf().uintval(); + constexpr uint32_t INF_BITS = FPBits::inf().uintval(); // x is 0, inf/nan, or negative. - if (LIBC_UNLIKELY(x_u == 0 || x_u >= INF_BIT)) { + if (LIBC_UNLIKELY(x_u == 0 || x_u >= INF_BITS)) { // x is NaN - if (x_abs > INF_BIT) { + if (x_abs > INF_BITS) { if (xbits.is_signaling_nan()) { fputil::raise_except_if_required(FE_INVALID); return FPBits::quiet_nan().get_val(); @@ -55,7 +55,7 @@ LIBC_INLINE static constexpr float rsqrtf(float x) { } // x = +inf => rsqrt(x) = 0 - return FPBits::zero().get_val(); + return FPBits::zero(xbits.sign()).get_val(); } // TODO: add float based approximation when diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index 2d92d7342ec96..54dc16d57baf5 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -996,7 +996,6 @@ add_entrypoint_object( ../rsqrtf.h DEPENDS libc.src.__support.math.rsqrtf - libc.src.errno.errno ) add_entrypoint_object( diff --git a/libc/src/math/generic/rsqrtf.cpp b/libc/src/math/generic/rsqrtf.cpp index 1c37979b35ed5..6a38fa7d43d2e 100644 --- a/libc/src/math/generic/rsqrtf.cpp +++ b/libc/src/math/generic/rsqrtf.cpp @@ -12,4 +12,5 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(float, rsqrtf, (float x)) { return math::rsqrtf(x); } + } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/math/RsqrtTest.h b/libc/test/src/math/RsqrtTest.h index 14cb708176237..d11d708f644d9 100644 --- a/libc/test/src/math/RsqrtTest.h +++ b/libc/test/src/math/RsqrtTest.h @@ -54,7 +54,7 @@ class RsqrtTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { FPBits x_bits(v); InType x = x_bits.get_val(); - if (x_bits.is_nan() || (x < static_cast(0))) + if (x_bits.is_nan() || x_bits.is_neg()) continue; ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Rsqrt, x, func(x), 0.5); } diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt index c73a870fc0c09..1583ab6f74680 100644 --- a/libc/test/src/math/exhaustive/CMakeLists.txt +++ b/libc/test/src/math/exhaustive/CMakeLists.txt @@ -37,7 +37,6 @@ add_fp_unittest( DEPENDS .exhaustive_test libc.src.math.rsqrtf - libc.src.__support.FPUtil.fp_bits LINK_LIBRARIES -lpthread ) diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 644fa90a412fa..28f20f7956551 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -3509,8 +3509,9 @@ add_fp_unittest( SRCS rsqrtf_test.cpp DEPENDS - libc.src.math.rsqrtf - libc.hdr.errno_macros + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.math.rsqrtf ) add_fp_unittest( @@ -3520,8 +3521,9 @@ add_fp_unittest( SRCS rsqrtf16_test.cpp DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros libc.src.math.rsqrtf16 - libc.hdr.errno_macros ) add_fp_unittest( diff --git a/libc/test/src/math/smoke/rsqrtf16_test.cpp b/libc/test/src/math/smoke/rsqrtf16_test.cpp index 5eb3e2fd6692c..c24972d7ba29d 100644 --- a/libc/test/src/math/smoke/rsqrtf16_test.cpp +++ b/libc/test/src/math/smoke/rsqrtf16_test.cpp @@ -6,7 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" +#include "hdr/errno_macros.h" #include "src/__support/FPUtil/cast.h" #include "src/math/rsqrtf16.h" #include "test/UnitTest/FPMatcher.h" diff --git a/libc/test/src/math/smoke/rsqrtf_test.cpp b/libc/test/src/math/smoke/rsqrtf_test.cpp index 02f67c4378197..0644c07d042a6 100644 --- a/libc/test/src/math/smoke/rsqrtf_test.cpp +++ b/libc/test/src/math/smoke/rsqrtf_test.cpp @@ -6,7 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" +#include "hdr/errno_macros.h" #include "src/math/rsqrtf.h" #include "test/UnitTest/FPMatcher.h" #include "test/UnitTest/Test.h" diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 87ad0926bfee6..1466545d50d3e 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -2300,13 +2300,12 @@ libc_support_library( name = "__support_math_rsqrtf", hdrs = ["src/__support/math/rsqrtf.h"], deps = [ - ":__support_fputil_fenv_impl", - ":__support_fputil_fp_bits", - ":__support_fputil_manipulation_functions", - ":__support_fputil_multiply_add", - ":__support_fputil_polyeval", - ":__support_macros_optimization", - ":__support_macros_properties_types", + ":hdr_errno_macros", + ":hdr_fenv_macros", + ":__support_fputil_cast", + ":__support_fputil_fenv_impl", + ":__support_fputil_fp_bits", + ":__support_macros_optimization", ], ) @@ -4507,7 +4506,6 @@ libc_math_function( name = "rsqrtf", additional_deps = [ ":__support_math_rsqrtf", - ":errno", ], ) From 0faacb661a3828aa8e64901e6c88b51d36c6eb57 Mon Sep 17 00:00:00 2001 From: Anton Shepelev Date: Wed, 24 Sep 2025 13:57:45 -0700 Subject: [PATCH 6/8] Clang-formatted the files in question, ran Buildifier on .bazel --- libc/src/__support/math/rsqrtf.h | 12 ++++++------ libc/test/src/math/smoke/rsqrtf16_test.cpp | 4 ++-- libc/test/src/math/smoke/rsqrtf_test.cpp | 4 ++-- utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libc/src/__support/math/rsqrtf.h b/libc/src/__support/math/rsqrtf.h index 2b2531f9fbc0f..cbdf2663f08c9 100644 --- a/libc/src/__support/math/rsqrtf.h +++ b/libc/src/__support/math/rsqrtf.h @@ -1,4 +1,4 @@ -//===-- Implementation header for rsqrtf ------------------------*- C++ -*-===// +//===-- Implementation header for rsqrtf ------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,11 +9,11 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF_H #define LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF_H -#include "hdr/errno_macros.h" -#include "hdr/fenv_macros.h" -#include "src/__support/FPUtil/FEnvImpl.h" -#include "src/__support/FPUtil/FPBits.h" -#include "src/__support/FPUtil/cast.h" +#include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/sqrt.h" #include "src/__support/macros/optimization.h" diff --git a/libc/test/src/math/smoke/rsqrtf16_test.cpp b/libc/test/src/math/smoke/rsqrtf16_test.cpp index c24972d7ba29d..24e8be400a366 100644 --- a/libc/test/src/math/smoke/rsqrtf16_test.cpp +++ b/libc/test/src/math/smoke/rsqrtf16_test.cpp @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "hdr/fenv_macros.h" -#include "hdr/errno_macros.h" +#include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" #include "src/__support/FPUtil/cast.h" #include "src/math/rsqrtf16.h" #include "test/UnitTest/FPMatcher.h" diff --git a/libc/test/src/math/smoke/rsqrtf_test.cpp b/libc/test/src/math/smoke/rsqrtf_test.cpp index 0644c07d042a6..d71b82c1e5be1 100644 --- a/libc/test/src/math/smoke/rsqrtf_test.cpp +++ b/libc/test/src/math/smoke/rsqrtf_test.cpp @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "hdr/fenv_macros.h" -#include "hdr/errno_macros.h" +#include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" #include "src/math/rsqrtf.h" #include "test/UnitTest/FPMatcher.h" #include "test/UnitTest/Test.h" diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 1466545d50d3e..a275bcbbd3e58 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -2300,12 +2300,12 @@ libc_support_library( name = "__support_math_rsqrtf", hdrs = ["src/__support/math/rsqrtf.h"], deps = [ - ":hdr_errno_macros", - ":hdr_fenv_macros", - ":__support_fputil_cast", - ":__support_fputil_fenv_impl", - ":__support_fputil_fp_bits", - ":__support_macros_optimization", + ":__support_fputil_cast", + ":__support_fputil_fenv_impl", + ":__support_fputil_fp_bits", + ":__support_macros_optimization", + ":hdr_errno_macros", + ":hdr_fenv_macros", ], ) From 471ef6264d7c430be87f161c48c2da8926218418 Mon Sep 17 00:00:00 2001 From: Anton Shepelev Date: Mon, 6 Oct 2025 22:51:50 -0700 Subject: [PATCH 7/8] Addressed the comments, except last Bazel one --- libc/src/__support/math/CMakeLists.txt | 18 +++++++++--------- libc/test/shared/shared_math_test.cpp | 1 + .../llvm-project-overlay/libc/BUILD.bazel | 1 - 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt index 7fd91e116ff0c..37a17b938b8ad 100644 --- a/libc/src/__support/math/CMakeLists.txt +++ b/libc/src/__support/math/CMakeLists.txt @@ -764,11 +764,12 @@ add_header_library( HDRS rsqrtf.h DEPENDS - libc.hdr.errno_macros - libc.hdr.fenv_macros - libc.src.__support.FPUtil.cast - libc.src.__support.FPUtil.fenv_impl - libc.src.__support.FPUtil.fp_bits + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.sqrt libc.src.__support.macros.optimization ) @@ -777,14 +778,13 @@ add_header_library( HDRS rsqrtf16.h DEPENDS + libc.hdr.errno_macros + libc.hdr.fenv_macros libc.src.__support.FPUtil.cast libc.src.__support.FPUtil.fenv_impl libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.multiply_add - libc.src.__support.FPUtil.polyeval - libc.src.__support.FPUtil.manipulation_functions + libc.src.__support.FPUtil.sqrt libc.src.__support.macros.optimization - libc.src.__support.macros.properties.types ) add_header_library( diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp index 46bd112549cbd..bea0580361032 100644 --- a/libc/test/shared/shared_math_test.cpp +++ b/libc/test/shared/shared_math_test.cpp @@ -67,6 +67,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat) { ASSERT_FP_EQ(float(8 << 5), LIBC_NAMESPACE::shared::ldexpf(8.0f, 5)); ASSERT_FP_EQ(float(-1 * (8 << 5)), LIBC_NAMESPACE::shared::ldexpf(-8.0f, 5)); + EXPECT_FP_EQ(0x1p+0f, LIBC_NAMESPACE::shared::rsqrtf(1.0f)); } diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index a275bcbbd3e58..caeb7f2b3efa3 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -4513,7 +4513,6 @@ libc_math_function( name = "rsqrtf16", additional_deps = [ ":__support_math_rsqrtf16", - ":errno", ], ) From f7387ddc41cf96b06b36d76c09241121d8890571 Mon Sep 17 00:00:00 2001 From: Anton Shepelev Date: Tue, 7 Oct 2025 08:26:56 -0700 Subject: [PATCH 8/8] Fixed typo in result variable --- libc/src/__support/math/rsqrtf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/src/__support/math/rsqrtf.h b/libc/src/__support/math/rsqrtf.h index cbdf2663f08c9..5da1e73109488 100644 --- a/libc/src/__support/math/rsqrtf.h +++ b/libc/src/__support/math/rsqrtf.h @@ -60,7 +60,7 @@ LIBC_INLINE static constexpr float rsqrtf(float x) { // TODO: add float based approximation when // LIBC_TARGET_CPU_HAS_FPU_DOUBLE is not defined - double result = 1.0f / fputil::sqrt(fputil::cast(x)); + double result = 1.0 / fputil::sqrt(fputil::cast(x)); return fputil::cast(result); }