[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