[libc-commits] [libc] [llvm] [libc][math] Refactor log10, log1p, log2 implementation to header-only in src/__support/math folder. (PR #176089)

Muhammad Bassiouni via libc-commits libc-commits at lists.llvm.org
Thu Jan 15 22:58:19 PST 2026


================
@@ -0,0 +1,1068 @@
+//===-- Double-precision log1p(x) 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_LOG1P_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_LOG1P_H
+
+#include "common_constants.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/double_double.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+namespace log1p_internal {
+// 128-bit precision dyadic floating point numbers.
+using Float128 = typename fputil::DyadicFloat<128>;
+
+using LIBC_NAMESPACE::operator""_u128;
+
+using namespace common_constants_internal;
+
+// R1[i] = 2^-8 * nearestint( 2^8 / (1 + i * 2^-7) )
+constexpr double R1[129] = {
+    0x1p0,     0x1.fcp-1, 0x1.f8p-1, 0x1.f4p-1, 0x1.fp-1,  0x1.ecp-1, 0x1.eap-1,
+    0x1.e6p-1, 0x1.e2p-1, 0x1.dep-1, 0x1.dap-1, 0x1.d8p-1, 0x1.d4p-1, 0x1.dp-1,
+    0x1.cep-1, 0x1.cap-1, 0x1.c8p-1, 0x1.c4p-1, 0x1.cp-1,  0x1.bep-1, 0x1.bap-1,
+    0x1.b8p-1, 0x1.b4p-1, 0x1.b2p-1, 0x1.bp-1,  0x1.acp-1, 0x1.aap-1, 0x1.a6p-1,
+    0x1.a4p-1, 0x1.a2p-1, 0x1.9ep-1, 0x1.9cp-1, 0x1.9ap-1, 0x1.98p-1, 0x1.94p-1,
+    0x1.92p-1, 0x1.9p-1,  0x1.8ep-1, 0x1.8ap-1, 0x1.88p-1, 0x1.86p-1, 0x1.84p-1,
+    0x1.82p-1, 0x1.8p-1,  0x1.7ep-1, 0x1.7ap-1, 0x1.78p-1, 0x1.76p-1, 0x1.74p-1,
+    0x1.72p-1, 0x1.7p-1,  0x1.6ep-1, 0x1.6cp-1, 0x1.6ap-1, 0x1.68p-1, 0x1.66p-1,
+    0x1.64p-1, 0x1.62p-1, 0x1.6p-1,  0x1.5ep-1, 0x1.5cp-1, 0x1.5ap-1, 0x1.58p-1,
+    0x1.58p-1, 0x1.56p-1, 0x1.54p-1, 0x1.52p-1, 0x1.5p-1,  0x1.4ep-1, 0x1.4cp-1,
+    0x1.4ap-1, 0x1.4ap-1, 0x1.48p-1, 0x1.46p-1, 0x1.44p-1, 0x1.42p-1, 0x1.42p-1,
+    0x1.4p-1,  0x1.3ep-1, 0x1.3cp-1, 0x1.3cp-1, 0x1.3ap-1, 0x1.38p-1, 0x1.36p-1,
+    0x1.36p-1, 0x1.34p-1, 0x1.32p-1, 0x1.3p-1,  0x1.3p-1,  0x1.2ep-1, 0x1.2cp-1,
+    0x1.2cp-1, 0x1.2ap-1, 0x1.28p-1, 0x1.28p-1, 0x1.26p-1, 0x1.24p-1, 0x1.24p-1,
+    0x1.22p-1, 0x1.2p-1,  0x1.2p-1,  0x1.1ep-1, 0x1.1cp-1, 0x1.1cp-1, 0x1.1ap-1,
+    0x1.1ap-1, 0x1.18p-1, 0x1.16p-1, 0x1.16p-1, 0x1.14p-1, 0x1.14p-1, 0x1.12p-1,
+    0x1.12p-1, 0x1.1p-1,  0x1.0ep-1, 0x1.0ep-1, 0x1.0cp-1, 0x1.0cp-1, 0x1.0ap-1,
+    0x1.0ap-1, 0x1.08p-1, 0x1.08p-1, 0x1.06p-1, 0x1.06p-1, 0x1.04p-1, 0x1.04p-1,
+    0x1.02p-1, 0x1.02p-1, 0x1p-1,
+};
+
+// Extra constants for exact range reduction when FMA instructions are not
+// available:
+// r * c - 1 for r = 2^-8 * nearestint( 2^8 / (1 + i * 2^-7))
+//           and c = 1 + i * 2^-7
+//           with i = 0..128.
+[[maybe_unused]] constexpr double RCM1[129] = {
+    0.0,        -0x1p-14,   -0x1p-12,   -0x1.2p-11,  -0x1p-10,   -0x1.9p-10,
+    0x1.fp-10,  0x1.28p-10, 0x1p-12,    -0x1.9p-11,  -0x1.fp-10, 0x1.2p-10,
+    -0x1p-12,   -0x1.cp-10, 0x1.1p-10,  -0x1.5p-11,  0x1p-9,     0x1p-14,
+    -0x1p-9,    0x1.ap-12,  -0x1.ep-10, 0x1.8p-12,   -0x1.1p-9,  -0x1p-15,
+    0x1p-9,     -0x1.ap-11, 0x1.1p-10,  -0x1.f8p-10, -0x1p-12,   0x1.68p-10,
+    -0x1.fp-10, -0x1.cp-12, 0x1p-10,    0x1.3p-9,    -0x1.6p-10, -0x1.4p-13,
+    0x1p-10,    0x1.0cp-9,  -0x1.08p-9, -0x1.2p-10,  -0x1p-12,   0x1.2p-11,
+    0x1.5p-10,  0x1p-9,     0x1.5p-9,   -0x1.1cp-9,  -0x1.cp-10, -0x1.58p-10,
+    -0x1p-10,   -0x1.7p-11, -0x1p-11,   -0x1.6p-12,  -0x1p-12,   -0x1.cp-13,
+    -0x1p-12,   -0x1.6p-12, -0x1p-11,   -0x1.7p-11,  -0x1p-10,   -0x1.58p-10,
+    -0x1.cp-10, -0x1.1cp-9, -0x1.6p-9,  0x1.5p-9,    0x1p-9,     0x1.5p-10,
+    0x1.2p-11,  -0x1p-12,   -0x1.2p-10, -0x1.08p-9,  -0x1.88p-9, 0x1.0cp-9,
+    0x1p-10,    -0x1.4p-13, -0x1.6p-10, -0x1.54p-9,  0x1.3p-9,   0x1p-10,
+    -0x1.cp-12, -0x1.fp-10, 0x1.8p-9,   0x1.68p-10,  -0x1p-12,   -0x1.f8p-10,
+    0x1.7p-9,   0x1.1p-10,  -0x1.ap-11, -0x1.6p-9,   0x1p-9,     -0x1p-15,
+    -0x1.1p-9,  0x1.48p-9,  0x1.8p-12,  -0x1.ep-10,  0x1.6p-9,   0x1.ap-12,
+    -0x1p-9,    0x1.48p-9,  0x1p-14,    -0x1.4p-9,   0x1p-9,     -0x1.5p-11,
+    -0x1.bp-9,  0x1.1p-10,  -0x1.cp-10, 0x1.54p-9,   -0x1p-12,   -0x1.9cp-9,
+    0x1.2p-10,  -0x1.fp-10, 0x1.3p-9,   -0x1.9p-11,  0x1.cp-9,   0x1p-12,
+    -0x1.88p-9, 0x1.28p-10, -0x1.2p-9,  0x1.fp-10,   -0x1.9p-10, 0x1.4cp-9,
+    -0x1p-10,   0x1.9p-9,   -0x1.2p-11, 0x1.c4p-9,   -0x1p-12,   0x1.e8p-9,
+    -0x1p-14,   0x1.fcp-9,  0.0,
+};
+
+// Generated by Sollya with:
+// for i from 0 to 128 do {
+//     r = 2^-8 * nearestint( 2^8 / (1 + i*2^-7) );
+//     b = nearestint(log(r)*2^43) * 2^-43;
+//     c = round(log(r) - b, D, RN);
+//     print("{", -c, ",", -b, "},");
+//   };
+// We replace LOG_R1_DD[128] with log(1.0) == 0.0
+alignas(16) constexpr fputil::DoubleDouble LOG_R1_DD[129] = {
+    {0.0, 0.0},
+    {-0x1.0c76b999d2be8p-46, 0x1.010157589p-7},
+    {-0x1.3dc5b06e2f7d2p-45, 0x1.0205658938p-6},
+    {-0x1.aa0ba325a0c34p-45, 0x1.8492528c9p-6},
+    {0x1.111c05cf1d753p-47, 0x1.0415d89e74p-5},
+    {-0x1.c167375bdfd28p-45, 0x1.466aed42ep-5},
+    {-0x1.29efbec19afa2p-47, 0x1.67c94f2d4cp-5},
+    {0x1.0fc1a353bb42ep-45, 0x1.aaef2d0fbp-5},
+    {-0x1.e113e4fc93b7bp-47, 0x1.eea31c006cp-5},
+    {-0x1.5325d560d9e9bp-45, 0x1.1973bd1466p-4},
+    {0x1.cc85ea5db4ed7p-45, 0x1.3bdf5a7d1ep-4},
+    {-0x1.53a2582f4e1efp-48, 0x1.4d3115d208p-4},
+    {0x1.c1e8da99ded32p-49, 0x1.700d30aeacp-4},
+    {0x1.3115c3abd47dap-45, 0x1.9335e5d594p-4},
+    {-0x1.e42b6b94407c8p-47, 0x1.a4e7640b1cp-4},
+    {0x1.646d1c65aacd3p-45, 0x1.c885801bc4p-4},
+    {0x1.a89401fa71733p-46, 0x1.da72763844p-4},
+    {-0x1.534d64fa10afdp-45, 0x1.fe89139dbep-4},
+    {0x1.1ef78ce2d07f2p-45, 0x1.1178e8227ep-3},
+    {0x1.ca78e44389934p-45, 0x1.1aa2b7e23fp-3},
+    {0x1.39d6ccb81b4a1p-47, 0x1.2d1610c868p-3},
+    {0x1.62fa8234b7289p-51, 0x1.365fcb0159p-3},
+    {0x1.5837954fdb678p-45, 0x1.4913d8333bp-3},
+    {0x1.633e8e5697dc7p-45, 0x1.527e5e4a1bp-3},
+    {-0x1.27023eb68981cp-46, 0x1.5bf406b544p-3},
+    {-0x1.5118de59c21e1p-45, 0x1.6f0128b757p-3},
+    {-0x1.c661070914305p-46, 0x1.7898d85445p-3},
+    {-0x1.73d54aae92cd1p-47, 0x1.8beafeb39p-3},
+    {0x1.7f22858a0ff6fp-47, 0x1.95a5adcf7p-3},
+    {0x1.9904d6865817ap-45, 0x1.9f6c407089p-3},
+    {-0x1.c358d4eace1aap-47, 0x1.b31d8575bdp-3},
+    {-0x1.d4bc4595412b6p-45, 0x1.bd087383bep-3},
+    {-0x1.1ec72c5962bd2p-48, 0x1.c6ffbc6f01p-3},
+    {-0x1.84a7e75b6f6e4p-47, 0x1.d1037f2656p-3},
+    {0x1.212276041f43p-51, 0x1.e530effe71p-3},
+    {-0x1.a211565bb8e11p-51, 0x1.ef5ade4ddp-3},
+    {0x1.bcbecca0cdf3p-46, 0x1.f991c6cb3bp-3},
+    {-0x1.6f08c1485e94ap-46, 0x1.01eae5626c8p-2},
+    {0x1.7188b163ceae9p-45, 0x1.0c42d67616p-2},
+    {-0x1.c210e63a5f01cp-45, 0x1.1178e8227e8p-2},
+    {0x1.b9acdf7a51681p-45, 0x1.16b5ccbacf8p-2},
+    {0x1.ca6ed5147bdb7p-45, 0x1.1bf99635a68p-2},
+    {0x1.a87deba46baeap-47, 0x1.214456d0eb8p-2},
+    {0x1.c93c1df5bb3b6p-45, 0x1.269621134d8p-2},
+    {0x1.a9cfa4a5004f4p-45, 0x1.2bef07cdc9p-2},
+    {0x1.16ecdb0f177c8p-46, 0x1.36b6776be1p-2},
+    {0x1.83b54b606bd5cp-46, 0x1.3c25277333p-2},
+    {0x1.8e436ec90e09dp-47, 0x1.419b423d5e8p-2},
+    {-0x1.f27ce0967d675p-45, 0x1.4718dc271c8p-2},
+    {-0x1.e20891b0ad8a4p-45, 0x1.4c9e09e173p-2},
+    {0x1.ebe708164c759p-45, 0x1.522ae0738ap-2},
+    {0x1.fadedee5d40efp-46, 0x1.57bf753c8dp-2},
+    {-0x1.a0b2a08a465dcp-47, 0x1.5d5bddf596p-2},
+    {-0x1.db623e731aep-45, 0x1.630030b3abp-2},
+    {0x1.0a0d32756ebap-45, 0x1.68ac83e9c68p-2},
+    {0x1.721657c222d87p-46, 0x1.6e60ee6af18p-2},
+    {0x1.d8b0949dc60b3p-45, 0x1.741d876c678p-2},
+    {0x1.9ec7d2efd1778p-45, 0x1.79e26687cf8p-2},
+    {-0x1.72090c812566ap-45, 0x1.7fafa3bd818p-2},
+    {0x1.fd56f3333778ap-45, 0x1.85855776dc8p-2},
+    {-0x1.05ae1e5e7047p-45, 0x1.8b639a88b3p-2},
+    {-0x1.766b52ee6307dp-46, 0x1.914a8635bf8p-2},
+    {-0x1.52313a502d9fp-46, 0x1.973a3431358p-2},
+    {-0x1.52313a502d9fp-46, 0x1.973a3431358p-2},
+    {-0x1.6279e10d0c0bp-45, 0x1.9d32bea15fp-2},
+    {0x1.3c6457f9d79f5p-45, 0x1.a33440224f8p-2},
+    {0x1.e36f2bea77a5dp-46, 0x1.a93ed3c8ad8p-2},
+    {-0x1.17cc552774458p-45, 0x1.af5295248dp-2},
+    {0x1.095252d841995p-46, 0x1.b56fa044628p-2},
+    {0x1.7d85bf40a666dp-45, 0x1.bb9611b80ep-2},
+    {0x1.cec807fe8e18p-45, 0x1.c1c60693fap-2},
+    {0x1.cec807fe8e18p-45, 0x1.c1c60693fap-2},
+    {-0x1.9b6ddc15249aep-45, 0x1.c7ff9c74558p-2},
+    {-0x1.797c33ec7a6bp-47, 0x1.ce42f180648p-2},
+    {0x1.35bafe9a767a8p-45, 0x1.d490246def8p-2},
+    {-0x1.ea42d60dc616ap-46, 0x1.dae75484c98p-2},
+    {-0x1.ea42d60dc616ap-46, 0x1.dae75484c98p-2},
+    {-0x1.326b207322938p-46, 0x1.e148a1a2728p-2},
+    {-0x1.465505372bd08p-45, 0x1.e7b42c3ddbp-2},
+    {0x1.f27f45a470251p-45, 0x1.ee2a156b41p-2},
+    {0x1.f27f45a470251p-45, 0x1.ee2a156b41p-2},
+    {0x1.2cde56f014a8bp-46, 0x1.f4aa7ee0318p-2},
+    {0x1.085fa3c164935p-47, 0x1.fb358af7a48p-2},
+    {-0x1.53ba3b1727b1cp-47, 0x1.00e5ae5b208p-1},
+    {-0x1.53ba3b1727b1cp-47, 0x1.00e5ae5b208p-1},
+    {-0x1.4c45fe79539ep-47, 0x1.04360be7604p-1},
+    {0x1.6812241edf5fdp-45, 0x1.078bf0533c4p-1},
+    {0x1.f486b887e7e27p-46, 0x1.0ae76e2d054p-1},
+    {0x1.f486b887e7e27p-46, 0x1.0ae76e2d054p-1},
+    {0x1.c299807801742p-46, 0x1.0e4898611ccp-1},
+    {-0x1.58647bb9ddcb2p-45, 0x1.11af823c75cp-1},
+    {-0x1.58647bb9ddcb2p-45, 0x1.11af823c75cp-1},
+    {-0x1.edd97a293ae49p-45, 0x1.151c3f6f298p-1},
+    {0x1.4cc4ef8ab465p-46, 0x1.188ee40f23cp-1},
+    {0x1.4cc4ef8ab465p-46, 0x1.188ee40f23cp-1},
+    {0x1.cacdeed70e667p-51, 0x1.1c07849ae6p-1},
+    {-0x1.a7242c9fe81d3p-45, 0x1.1f8635fc618p-1},
+    {-0x1.a7242c9fe81d3p-45, 0x1.1f8635fc618p-1},
+    {0x1.2fc066e48667bp-46, 0x1.230b0d8bebcp-1},
+    {-0x1.b61f10522625p-47, 0x1.269621134dcp-1},
+    {-0x1.b61f10522625p-47, 0x1.269621134dcp-1},
+    {0x1.06d2be797882dp-45, 0x1.2a2786d0ecp-1},
+    {-0x1.7a6e507b9dc11p-46, 0x1.2dbf557b0ep-1},
+    {-0x1.7a6e507b9dc11p-46, 0x1.2dbf557b0ep-1},
+    {-0x1.74e93c5a0ed9cp-45, 0x1.315da443408p-1},
+    {-0x1.74e93c5a0ed9cp-45, 0x1.315da443408p-1},
+    {0x1.0b83f9527e6acp-46, 0x1.35028ad9d8cp-1},
+    {-0x1.18b7abb5569a4p-45, 0x1.38ae2171978p-1},
+    {-0x1.18b7abb5569a4p-45, 0x1.38ae2171978p-1},
+    {-0x1.2b7367cfe13c2p-47, 0x1.3c6080c36cp-1},
+    {-0x1.2b7367cfe13c2p-47, 0x1.3c6080c36cp-1},
+    {-0x1.6ce7930f0c74cp-45, 0x1.4019c2125ccp-1},
+    {-0x1.6ce7930f0c74cp-45, 0x1.4019c2125ccp-1},
+    {-0x1.d984f481051f7p-48, 0x1.43d9ff2f924p-1},
+    {-0x1.2cb6af94d60aap-45, 0x1.47a1527e8a4p-1},
+    {-0x1.2cb6af94d60aap-45, 0x1.47a1527e8a4p-1},
+    {0x1.f7115ed4c541cp-49, 0x1.4b6fd6f970cp-1},
+    {0x1.f7115ed4c541cp-49, 0x1.4b6fd6f970cp-1},
+    {-0x1.e6c516d93b8fbp-45, 0x1.4f45a835a5p-1},
+    {-0x1.e6c516d93b8fbp-45, 0x1.4f45a835a5p-1},
+    {0x1.5ccc45d257531p-47, 0x1.5322e268678p-1},
+    {0x1.5ccc45d257531p-47, 0x1.5322e268678p-1},
+    {0x1.9980bff3303ddp-47, 0x1.5707a26bb8cp-1},
+    {0x1.9980bff3303ddp-47, 0x1.5707a26bb8cp-1},
+    {0x1.dfa63ac10c9fbp-45, 0x1.5af405c3648p-1},
+    {0x1.dfa63ac10c9fbp-45, 0x1.5af405c3648p-1},
+    {0x1.202380cda46bep-45, 0x1.5ee82aa2418p-1},
+    {0x1.202380cda46bep-45, 0x1.5ee82aa2418p-1},
+    {0.0, 0.0},
+};
+
+// Degree-7 minimax polynomial log(1 + v) ~ v - v^2 / 2 + ...
+// generated by Sollya with:
+// > P = fpminimax(log(1 + x)/x, 6, [|1, 1, D...|],
+//                 [-0x1.69000000000edp-8, 0x1.7f00000000081p-8]);
+constexpr double P_COEFFS[6] = {-0x1p-1,
----------------
bassiounix wrote:

```suggestion
LIBC_INLINE_VAR constexpr double P_COEFFS[6] = {-0x1p-1,
```

https://github.com/llvm/llvm-project/pull/176089


More information about the libc-commits mailing list