[libcxx-commits] [libcxx] 09d7b89 - [libc++] Add a thread-safe version of std::lgamma in the dylib (#153631)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 25 10:46:55 PST 2026


Author: Louis Dionne
Date: 2026-02-25T13:46:51-05:00
New Revision: 09d7b890e035c8ace45642f27edc0ff5768311eb

URL: https://github.com/llvm/llvm-project/commit/09d7b890e035c8ace45642f27edc0ff5768311eb
DIFF: https://github.com/llvm/llvm-project/commit/09d7b890e035c8ace45642f27edc0ff5768311eb.diff

LOG: [libc++] Add a thread-safe version of std::lgamma in the dylib (#153631)

Libc++ currently redeclares ::lgamma_r on platforms that provide it.
This causes issues when building with modules, and redeclaring functions
provided by another library (here the C library) is bad hygiene.

Instead, use an asm declaration to call the right function without
having to redeclare it.

Added: 
    

Modified: 
    libcxx/include/__math/gamma.h
    libcxx/include/__random/binomial_distribution.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__math/gamma.h b/libcxx/include/__math/gamma.h
index 693e111a84e99..6c82cbf0cae93 100644
--- a/libcxx/include/__math/gamma.h
+++ b/libcxx/include/__math/gamma.h
@@ -55,6 +55,32 @@ inline _LIBCPP_HIDE_FROM_ABI double tgamma(_A1 __x) _NOEXCEPT {
   return __builtin_tgamma((double)__x);
 }
 
+// __lgamma_r
+//
+// POSIX systems provide a function named lgamma_r which is a reentrant version of lgamma. Use that
+// whenever possible. However, we avoid re-declaring the actual function since 
diff erent platforms
+// declare it 
diff erently in the first place: instead use `asm` to get the compiler to call the right
+// function.
+
+#if defined(_LIBCPP_MSVCRT_LIKE) // reentrant version is not available on Windows
+
+inline _LIBCPP_HIDE_FROM_ABI double __lgamma_r(double __d) _NOEXCEPT { return __builtin_lgamma(__d); }
+
+#else
+
+#  if defined(_LIBCPP_OBJECT_FORMAT_MACHO)
+double __lgamma_r_shim(double, int*) _NOEXCEPT __asm__("_lgamma_r");
+#  else
+double __lgamma_r_shim(double, int*) _NOEXCEPT __asm__("lgamma_r");
+#  endif
+
+inline _LIBCPP_HIDE_FROM_ABI double __lgamma_r(double __d) _NOEXCEPT {
+  int __sign;
+  return __math::__lgamma_r_shim(__d, &__sign);
+}
+
+#endif
+
 } // namespace __math
 
 _LIBCPP_END_NAMESPACE_STD

diff  --git a/libcxx/include/__random/binomial_distribution.h b/libcxx/include/__random/binomial_distribution.h
index 6d07ff3c7df04..76996abacb3ac 100644
--- a/libcxx/include/__random/binomial_distribution.h
+++ b/libcxx/include/__random/binomial_distribution.h
@@ -10,6 +10,7 @@
 #define _LIBCPP___RANDOM_BINOMIAL_DISTRIBUTION_H
 
 #include <__config>
+#include <__math/gamma.h>
 #include <__random/is_valid.h>
 #include <__random/uniform_real_distribution.h>
 #include <cmath>
@@ -97,33 +98,13 @@ class binomial_distribution {
   }
 };
 
-// Some libc declares the math functions to be `noexcept`.
-#if _LIBCPP_GLIBC_PREREQ(2, 8) || _LIBCPP_LIBC_LLVM_LIBC
-#  define _LIBCPP_LGAMMA_R_NOEXCEPT _NOEXCEPT
-#else
-#  define _LIBCPP_LGAMMA_R_NOEXCEPT
-#endif
-
-#if !defined(_LIBCPP_MSVCRT_LIKE)
-extern "C" double lgamma_r(double, int*) _LIBCPP_LGAMMA_R_NOEXCEPT;
-#endif
-
-inline _LIBCPP_HIDE_FROM_ABI double __libcpp_lgamma(double __d) {
-#if defined(_LIBCPP_MSVCRT_LIKE)
-  return lgamma(__d);
-#else
-  int __sign;
-  return lgamma_r(__d, &__sign);
-#endif
-}
-
 template <class _IntType>
 binomial_distribution<_IntType>::param_type::param_type(result_type __t, double __p) : __t_(__t), __p_(__p) {
   if (0 < __p_ && __p_ < 1) {
     __r0_ = static_cast<result_type>((__t_ + 1) * __p_);
-    __pr_ = std::exp(
-        std::__libcpp_lgamma(__t_ + 1.) - std::__libcpp_lgamma(__r0_ + 1.) - std::__libcpp_lgamma(__t_ - __r0_ + 1.) +
-        __r0_ * std::log(__p_) + (__t_ - __r0_) * std::log(1 - __p_));
+    __pr_ =
+        std::exp(__math::__lgamma_r(__t_ + 1.) - __math::__lgamma_r(__r0_ + 1.) -
+                 __math::__lgamma_r(__t_ - __r0_ + 1.) + __r0_ * std::log(__p_) + (__t_ - __r0_) * std::log(1 - __p_));
     __odds_ratio_ = __p_ / (1 - __p_);
   }
 }


        


More information about the libcxx-commits mailing list