[libc-commits] [libc] [libc][math] Refactor sqrti to header-only (PR #177960)

Vedant Neve via libc-commits libc-commits at lists.llvm.org
Thu Feb 12 10:00:16 PST 2026


https://github.com/0bVdnt updated https://github.com/llvm/llvm-project/pull/177960

>From 9b3107d37c3da801db48ac4744578b47887eba00 Mon Sep 17 00:00:00 2001
From: Vedant Neve <vedantneve13 at gmail.com>
Date: Sat, 31 Jan 2026 20:19:45 +0000
Subject: [PATCH 1/4] [libc][math] Refactor sqrti to header-only implementation

---
 libc/shared/math.h                     |  1 +
 libc/shared/math/sqrti.h               | 23 ++++++++++++
 libc/src/__support/math/CMakeLists.txt | 11 ++++++
 libc/src/__support/math/sqrti.h        | 52 ++++++++++++++++++++++++++
 4 files changed, 87 insertions(+)
 create mode 100644 libc/shared/math/sqrti.h
 create mode 100644 libc/src/__support/math/sqrti.h

diff --git a/libc/shared/math.h b/libc/shared/math.h
index eab584aea4e60..32e0043562f29 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -116,6 +116,7 @@
 #include "math/sqrtf.h"
 #include "math/sqrtf128.h"
 #include "math/sqrtf16.h"
+#include "math/sqrti.h"
 #include "math/tan.h"
 #include "math/tanf.h"
 
diff --git a/libc/shared/math/sqrti.h b/libc/shared/math/sqrti.h
new file mode 100644
index 0000000000000..d2829eff16b26
--- /dev/null
+++ b/libc/shared/math/sqrti.h
@@ -0,0 +1,23 @@
+//===-- Shared header for sqrti ---------------------------------*- 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_SQRTI_H
+#define LLVM_LIBC_SHARED_MATH_SQRTI_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/sqrti.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::sqrti;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_SQRTI_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 4e6e9bd6233ec..4223487447dc1 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -1638,6 +1638,17 @@ add_header_library(
     libc.src.__support.FPUtil.sqrt
 )
 
+add_header_library(
+  sqrti
+  HDRS
+    sqrti.h
+  DEPENDS
+    libc.src.__support.CPP.bit
+    libc.src.__support.CPP.type_traits
+    libc.src.__support.macros.attributes
+    libc.src.__support.macros.config
+)
+
 add_header_library(
   dfmal
   HDRS
diff --git a/libc/src/__support/math/sqrti.h b/libc/src/__support/math/sqrti.h
new file mode 100644
index 0000000000000..e8534febeb678
--- /dev/null
+++ b/libc/src/__support/math/sqrti.h
@@ -0,0 +1,52 @@
+//===-- Implementation header for sqrti -------------------------*- 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_SQRTI_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_SQRTI_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+template <typename T>
+LIBC_INLINE static constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T> sqrti(T n) {
+  if (n == 0)
+    return 0;
+
+  // The smallest power of 2 such that (1 << shift) >= sqrt(n).
+  // log2_n approx = (bits - 1) - clz(n)
+  // shift = ceil(log2_n / 2)
+  int bits = static_cast<int>(sizeof(T) * 8);
+  int lz = cpp::countl_zero(n);
+  int log2_n = bits - 1 - lz;
+  int shift = (log2_n / 2) + 1;
+  
+  // 'x' is guaranteed to be >= sqrt(n).
+  // This satisfies the condition for Newton-Raphson to converge monotonically.
+  T x = T(1) << shift;
+
+  // Newton-Raphson Iteration: x_{k+1} = (x_k + n / x_k) / 2
+  // the sequence decreases to floor(sqrt(n)).
+  while (true) {
+    T next = (x + n / x) / 2;
+    if (next >= x)
+      return x;
+    x = next;
+  }
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_SQRTI_H

>From 456fa3b9701b32a48baf7f89f6b92b3cce54af0d Mon Sep 17 00:00:00 2001
From: Vedant Neve <vedantneve13 at gmail.com>
Date: Sat, 31 Jan 2026 20:19:45 +0000
Subject: [PATCH 2/4] [libc][math] Refactor sqrti to header-only implementation

---
 libc/src/__support/math/sqrti.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libc/src/__support/math/sqrti.h b/libc/src/__support/math/sqrti.h
index e8534febeb678..f98dcd58a2944 100644
--- a/libc/src/__support/math/sqrti.h
+++ b/libc/src/__support/math/sqrti.h
@@ -19,7 +19,8 @@ namespace LIBC_NAMESPACE_DECL {
 namespace math {
 
 template <typename T>
-LIBC_INLINE static constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T> sqrti(T n) {
+LIBC_INLINE static constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+sqrti(T n) {
   if (n == 0)
     return 0;
 
@@ -30,7 +31,7 @@ LIBC_INLINE static constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T> sqrti(T
   int lz = cpp::countl_zero(n);
   int log2_n = bits - 1 - lz;
   int shift = (log2_n / 2) + 1;
-  
+
   // 'x' is guaranteed to be >= sqrt(n).
   // This satisfies the condition for Newton-Raphson to converge monotonically.
   T x = T(1) << shift;

>From ebcae77e57770a67ae043a2add4e78d410c59003 Mon Sep 17 00:00:00 2001
From: Vedant Neve <vedantneve13 at gmail.com>
Date: Thu, 12 Feb 2026 17:43:44 +0000
Subject: [PATCH 3/4] [libc][math] Add minimal shared sqrti test coverage and
 constexpr cleanup

---
 libc/src/__support/math/sqrti.h       | 2 +-
 libc/test/shared/CMakeLists.txt       | 1 +
 libc/test/shared/shared_math_test.cpp | 2 ++
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/math/sqrti.h b/libc/src/__support/math/sqrti.h
index f98dcd58a2944..630d160c3970d 100644
--- a/libc/src/__support/math/sqrti.h
+++ b/libc/src/__support/math/sqrti.h
@@ -19,7 +19,7 @@ namespace LIBC_NAMESPACE_DECL {
 namespace math {
 
 template <typename T>
-LIBC_INLINE static constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
 sqrti(T n) {
   if (n == 0)
     return 0;
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index ef4d78584ef77..d12998c99ca1f 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -112,6 +112,7 @@ add_fp_unittest(
     libc.src.__support.math.sqrtf128
     libc.src.__support.math.sinpif
     libc.src.__support.math.sqrt
+    libc.src.__support.math.sqrti
     libc.src.__support.math.sqrtf
     libc.src.__support.math.tan
     libc.src.__support.math.tanf
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 1c8463d9321fc..c060851a8edeb 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -125,6 +125,8 @@ TEST(LlvmLibcSharedMathTest, AllFloat) {
   EXPECT_FP_EQ(0x0p+0f, LIBC_NAMESPACE::shared::sinpif(0.0f));
   EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::sinf(0.0f));
   EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::sqrtf(0.0f));
+  EXPECT_EQ(3u, LIBC_NAMESPACE::shared::sqrti(10u));
+  EXPECT_EQ(65535u, LIBC_NAMESPACE::shared::sqrti(4294836225u));
   EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::tanf(0.0f));
 }
 

>From 451e6faa5f81ba0a8596853e73331028f000ab68 Mon Sep 17 00:00:00 2001
From: Vedant Neve <vedantneve13 at gmail.com>
Date: Thu, 12 Feb 2026 17:58:13 +0000
Subject: [PATCH 4/4] Format code

---
 libc/src/__support/math/sqrti.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libc/src/__support/math/sqrti.h b/libc/src/__support/math/sqrti.h
index 630d160c3970d..69f034e69f5e9 100644
--- a/libc/src/__support/math/sqrti.h
+++ b/libc/src/__support/math/sqrti.h
@@ -19,8 +19,7 @@ namespace LIBC_NAMESPACE_DECL {
 namespace math {
 
 template <typename T>
-LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T>
-sqrti(T n) {
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, T> sqrti(T n) {
   if (n == 0)
     return 0;
 



More information about the libc-commits mailing list