[libc-commits] [libc] [llvm] [libc][math] Add ExceptValues table for log1pf16 hard-to-round cases (PR #224152)
Youssef Ahmed via libc-commits
libc-commits at lists.llvm.org
Fri Sep 18 01:55:03 PDT 2026
https://github.com/usefahmed07 updated https://github.com/llvm/llvm-project/pull/224152
>From 94cc36ef3df05b45c6fce9814c9b2cd20b484c48 Mon Sep 17 00:00:00 2001
From: usefahmed07 <youssef.ahmed.hamaza at gmail.com>
Date: Thu, 17 Sep 2026 01:32:02 +0300
Subject: [PATCH 1/2] [libc][math] Add ExceptValues table for log1pf16
hard-to-round cases
Fixes #189543
---
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/src/__support/math/log1pf16.h | 141 +++++++++++++++++++++++
libc/src/math/CMakeLists.txt | 1 +
libc/src/math/generic/CMakeLists.txt | 11 ++
libc/src/math/generic/log1pf16.cpp | 18 +++
libc/src/math/log1pf16.h | 21 ++++
6 files changed, 193 insertions(+)
create mode 100644 libc/src/__support/math/log1pf16.h
create mode 100644 libc/src/math/generic/log1pf16.cpp
create mode 100644 libc/src/math/log1pf16.h
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 3f4e563e54359..81b4ba218458f 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -977,6 +977,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.llroundf16
libc.src.math.log10f16
libc.src.math.log10p1f16
+ libc.src.math.log1pf16
libc.src.math.log2f16
libc.src.math.log2p1f16
libc.src.math.logbf16
diff --git a/libc/src/__support/math/log1pf16.h b/libc/src/__support/math/log1pf16.h
new file mode 100644
index 0000000000000..14b1a227a2aae
--- /dev/null
+++ b/libc/src/__support/math/log1pf16.h
@@ -0,0 +1,141 @@
+//===-- Implementation header for log1pf16 -----------------------*- 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_LOG1PF16_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_LOG1PF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "expxf16_utils.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/PolyEval.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+LIBC_INLINE float16 log1pf16(float16 x) {
+ using namespace math::expxf16_internal;
+ using FPBits = fputil::FPBits<float16>;
+ FPBits x_bits(x);
+
+ uint16_t x_u = x_bits.uintval();
+ uint16_t x_abs = x_u & 0x7fffU;
+
+ constexpr size_t N_LOG1PF16_EXCEPTS = 6;
+ constexpr fputil::ExceptValues<float16, N_LOG1PF16_EXCEPTS>
+ LOG1PF16_EXCEPTS = {{
+ // (input, RZ output, RU offset, RD offset, RN offset)
+ // x = 0x1.f24p-7, log1pf16(x) = 0x1.ee4p-7 (RZ)
+ {0x23C9U, 0x23B9U, 1U, 0U, 1U},
+ // x = 0x1.988p0, log1pf16(x) = 0x1.e84p-1 (RZ)
+ {0x3E62U, 0x3BA1U, 1U, 0U, 1U},
+ // x = -0x1.e5p-7, log1pf16(x) = -0x1.e88p-7 (RZ)
+ {0xA394U, 0xA3A2U, 0U, 1U, 1U},
+ // x = -0x1.ed4p-7, log1pf16(x) = -0x1.f1p-7 (RZ)
+ {0xA3B5U, 0xA3C4U, 0U, 1U, 0U},
+ // x = -0x1.ae4p-6, log1pf16(x) = -0x1.b4p-6 (RZ)
+ {0xA6B9U, 0xA6D0U, 0U, 1U, 0U},
+ // x = -0x1.f6cp-6, log1pf16(x) = -0x1.fe8p-6 (RZ)
+ {0xA7DBU, 0xA7FAU, 0U, 1U, 1U},
+ }};
+
+ if (auto r = LOG1PF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+
+ // If x is NaN, +/-inf, or |x| <= 2^-3.
+ if (LIBC_UNLIKELY(x_abs <= 0x3000U || x_abs >= 0x7c00U)) {
+ if (x_bits.is_nan()) {
+ if (x_bits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ return x;
+ }
+
+ if (x_abs <= 0x3000U) {
+ // log1p(+/-0) = +/-0
+ if (x_abs == 0U)
+ return x;
+
+ // Degree-5 minimax polynomial generated by Sollya with:
+ // > display = hexadecimal;
+ // > P = fpminimax(log(1 + x)/x, [|0, 1, 2, 3, 4|], [|SG...|],
+ // [-2^-3, 2^-3]);
+ // > x * P;
+ // > dirtyinfnorm((log(1 + x) - x*P) / log(1 + x), [-2^-3, 2^-3]);
+ // 0x1.65afe505af70502b729765651fe9ef9d2071f0f89p-22
+ float xf = x;
+ return fputil::cast<float16>(
+ xf * fputil::polyeval(xf, 0x1p+0f, -0x1.fffc9cp-2f, 0x1.555174p-2f,
+ -0x1.03601ap-2f, 0x1.9ff8eep-3f));
+ }
+
+ if (x_u == 0x7c00U)
+ return FPBits::inf().get_val();
+
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ // log1p(-1) = -inf
+ if (LIBC_UNLIKELY(x_u == 0xbc00U)) {
+ fputil::raise_except_if_required(FE_DIVBYZERO);
+ return FPBits::inf(Sign::NEG).get_val();
+ }
+
+ // log1p(x) = NaN for x < -1
+ if (LIBC_UNLIKELY(x_u > 0xbc00U)) {
+ fputil::set_errno_if_required(EDOM);
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+
+ float xf = x;
+ float y = 1.0f + xf;
+
+ using FPBitsFloat = fputil::FPBits<float>;
+ FPBitsFloat y_bits(y);
+
+ if (LIBC_UNLIKELY(y_bits.is_zero()))
+ return FPBits::inf(Sign::NEG).get_val();
+
+ int m = y_bits.get_exponent();
+ y_bits.set_biased_exponent(FPBitsFloat::EXP_BIAS);
+ float mant_f = y_bits.get_val();
+ int f = y_bits.get_mantissa() >> (FPBitsFloat::FRACTION_LEN - 5);
+
+ float v = fputil::multiply_add(mant_f, ONE_OVER_F_F[f], -1.0f);
+
+ // Reusing the same log(1+v)/v minimax poly already used in logf16.h.
+ float log1p_d_over_f =
+ v * fputil::polyeval(v, 0x1p+0f, -0x1.001804p-1f, 0x1.557ef6p-2f);
+ float log_1_mant = LOGF_F[f] + log1p_d_over_f;
+ return fputil::cast<float16>(
+ fputil::multiply_add(static_cast<float>(m), LOGF_2, log_1_mant));
+}
+
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LOG1PF16_H
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 2c7568f0b6361..1cbcc282f6948 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -405,6 +405,7 @@ add_math_entrypoint_object(log10p1f16)
add_math_entrypoint_object(log1p)
add_math_entrypoint_object(log1pf)
+add_math_entrypoint_object(log1pf16)
add_math_entrypoint_object(log2)
add_math_entrypoint_object(log2f)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 28b8e954530dd..03a6106959b81 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1791,6 +1791,17 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ log1pf16
+ SRCS
+ log1pf16.cpp
+ HDRS
+ ../log1pf16.h
+ DEPENDS
+ libc.src.__support.math.log1pf16
+ libc.src.errno.errno
+)
+
add_entrypoint_object(
log2p1f16
SRCS
diff --git a/libc/src/math/generic/log1pf16.cpp b/libc/src/math/generic/log1pf16.cpp
new file mode 100644
index 0000000000000..123426202d7dd
--- /dev/null
+++ b/libc/src/math/generic/log1pf16.cpp
@@ -0,0 +1,18 @@
+//===-- Half-precision log(1+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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/log1pf16.h"
+#include "src/__support/math/log1pf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float16, log1pf16, (float16 x)) {
+ return math::log1pf16(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/log1pf16.h b/libc/src/math/log1pf16.h
new file mode 100644
index 0000000000000..2fdfe19bf7da9
--- /dev/null
+++ b/libc/src/math/log1pf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for log1pf16 -----------------------*- 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_LOG1PF16_H
+#define LLVM_LIBC_SRC_MATH_LOG1PF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 log1pf16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_LOG1PF16_H
>From ec3d757ec97961256b03437260edfc49a3bcd78d Mon Sep 17 00:00:00 2001
From: usefahmed07 <youssef.ahmed.hamaza at gmail.com>
Date: Fri, 18 Sep 2026 11:54:26 +0300
Subject: [PATCH 2/2] [libc][math] Complete registration checklist for log1pf16
Adds math.yaml entry, entrypoints across all supported platforms
(gpu/amdgpu, gpu/nvptx, baremetal/riscv, baremetal/aarch64,
freebsd/x86_64, darwin/aarch64, linux/riscv, linux/aarch64), and
shared math library support (shared/math.h, shared/math/log1pf16.h,
shared_math_test.cpp) per the add_math_function.md checklist.
---
libc/config/baremetal/aarch64/entrypoints.txt | 1 +
libc/config/baremetal/riscv/entrypoints.txt | 1 +
libc/config/darwin/aarch64/entrypoints.txt | 1 +
libc/config/freebsd/x86_64/entrypoints.txt | 1 +
libc/config/gpu/amdgpu/entrypoints.txt | 1 +
libc/config/gpu/nvptx/entrypoints.txt | 1 +
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/include/math.yaml | 7 +++
libc/shared/math.h | 1 +
libc/shared/math/log1pf16.h | 29 +++++++++++
libc/src/__support/math/CMakeLists.txt | 18 +++++++
libc/test/shared/CMakeLists.txt | 1 +
libc/test/shared/shared_math_test.cpp | 1 +
libc/test/src/math/CMakeLists.txt | 11 +++++
libc/test/src/math/log1pf16_test.cpp | 49 +++++++++++++++++++
libc/test/src/math/smoke/CMakeLists.txt | 13 +++++
libc/test/src/math/smoke/log1pf16_test.cpp | 48 ++++++++++++++++++
.../llvm-project-overlay/libc/BUILD.bazel | 28 +++++++++++
.../libc/test/src/math/BUILD.bazel | 2 +
20 files changed, 216 insertions(+)
create mode 100644 libc/shared/math/log1pf16.h
create mode 100644 libc/test/src/math/log1pf16_test.cpp
create mode 100644 libc/test/src/math/smoke/log1pf16_test.cpp
diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 757e4729699d1..88848562eb694 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -699,6 +699,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.log10f16
libc.src.math.log10p1f16
libc.src.math.log2f16
+ libc.src.math.log1pf16
libc.src.math.log2p1f16
libc.src.math.logbf16
libc.src.math.logf16
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 622d6156cff11..a1d9806a87f51 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -707,6 +707,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.log10f16
libc.src.math.log10p1f16
libc.src.math.log2f16
+ libc.src.math.log1pf16
libc.src.math.log2p1f16
libc.src.math.logbf16
libc.src.math.logf16
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index d702b2c5a6549..19f5324e71114 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -526,6 +526,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.log10f16
libc.src.math.log10p1f16
libc.src.math.log2f16
+ libc.src.math.log1pf16
libc.src.math.log2p1f16
libc.src.math.logbf16
libc.src.math.logf16
diff --git a/libc/config/freebsd/x86_64/entrypoints.txt b/libc/config/freebsd/x86_64/entrypoints.txt
index 8f6c178301c2f..60ce0a98e6f05 100644
--- a/libc/config/freebsd/x86_64/entrypoints.txt
+++ b/libc/config/freebsd/x86_64/entrypoints.txt
@@ -468,6 +468,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.log10f16
libc.src.math.log10p1f16
libc.src.math.log2f16
+ libc.src.math.log1pf16
libc.src.math.log2p1f16
libc.src.math.logbf16
libc.src.math.logf16
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 5c5e5891da822..c8a3df8da9256 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -640,6 +640,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.log10f16
libc.src.math.log10p1f16
libc.src.math.log2f16
+ libc.src.math.log1pf16
libc.src.math.log2p1f16
libc.src.math.logbf16
libc.src.math.logf16
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index afae725484a89..ceb0f59b379dd 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -638,6 +638,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.log10f16
libc.src.math.log10p1f16
libc.src.math.log2f16
+ libc.src.math.log1pf16
libc.src.math.log2p1f16
libc.src.math.logbf16
libc.src.math.logf16
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index a63d6ad6282c1..fa433ccd3de56 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -887,6 +887,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.llrintf16
libc.src.math.llroundf16
libc.src.math.log10p1f16
+ libc.src.math.log1pf16
libc.src.math.log2p1f16
libc.src.math.logbf16
libc.src.math.lrintf16
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index e8180cbb0c70e..462b59ba77a3c 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -967,6 +967,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
libc.src.math.log10f16
libc.src.math.log10p1f16
libc.src.math.log2f16
+ libc.src.math.log1pf16
libc.src.math.log2p1f16
libc.src.math.logbf16
libc.src.math.logf16
diff --git a/libc/include/math.yaml b/libc/include/math.yaml
index 006233e579f86..84ef73c323819 100644
--- a/libc/include/math.yaml
+++ b/libc/include/math.yaml
@@ -1868,6 +1868,13 @@ functions:
arguments:
- type: _Float16
guard: LIBC_TYPES_HAS_FLOAT16
+ - name: log1pf16
+ standards:
+ - stdc
+ return_type: _Float16
+ arguments:
+ - type: _Float16
+ guard: LIBC_TYPES_HAS_FLOAT16
- name: log2p1f16
standards:
- stdc
diff --git a/libc/shared/math.h b/libc/shared/math.h
index 7b52cedf99c24..0c883b5d480b2 100644
--- a/libc/shared/math.h
+++ b/libc/shared/math.h
@@ -337,6 +337,7 @@
#include "math/log10p1f16.h"
#include "math/log1p.h"
#include "math/log1pf.h"
+#include "math/log1pf16.h"
#include "math/log2.h"
#include "math/log2f.h"
#include "math/log2f16.h"
diff --git a/libc/shared/math/log1pf16.h b/libc/shared/math/log1pf16.h
new file mode 100644
index 0000000000000..5622b03eba366
--- /dev/null
+++ b/libc/shared/math/log1pf16.h
@@ -0,0 +1,29 @@
+//===-- Shared log1pf16 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_LOG1PF16_H
+#define LLVM_LIBC_SHARED_MATH_LOG1PF16_H
+
+#include "include/llvm-libc-macros/float16-macros.h"
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+
+#include "shared/libc_common.h"
+#include "src/__support/math/log1pf16.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::log1pf16;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#endif // LLVM_LIBC_SHARED_MATH_LOG1PF16_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 0871a5bf229b6..1c3fbd2ff9c42 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -5066,6 +5066,24 @@ add_header_library(
libc.src.__support.macros.properties.cpu_features
)
+add_header_library(
+ log1pf16
+ HDRS
+ log1pf16.h
+ DEPENDS
+ .expxf16_utils
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.except_value_utils
+ 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.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
+)
+
add_header_library(
log2p1f16
HDRS
diff --git a/libc/test/shared/CMakeLists.txt b/libc/test/shared/CMakeLists.txt
index 74eda7cdaf065..749218b759dd4 100644
--- a/libc/test/shared/CMakeLists.txt
+++ b/libc/test/shared/CMakeLists.txt
@@ -334,6 +334,7 @@ else()
libc.src.__support.math.log10f
libc.src.__support.math.log1p
libc.src.__support.math.log1pf
+ libc.src.__support.math.log1pf16
libc.src.__support.math.log2
libc.src.__support.math.logb
libc.src.__support.math.log2f
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index 7b785331f36c6..d926f52998b69 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -60,6 +60,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat16) {
EXPECT_FP_EQ(1.0f16, LIBC_NAMESPACE::shared::log10f16(10.0f16));
EXPECT_FP_EQ(1.0f16, LIBC_NAMESPACE::shared::log10p1f16(9.0f16));
EXPECT_FP_EQ(1.0f16, LIBC_NAMESPACE::shared::log2f16(2.0f16));
+ EXPECT_FP_EQ(0.0f16, LIBC_NAMESPACE::shared::log1pf16(0.0f16));
EXPECT_FP_EQ(1.0f16, LIBC_NAMESPACE::shared::log2p1f16(1.0f16));
EXPECT_FP_EQ(0.0f16, LIBC_NAMESPACE::shared::logbf16(1.0f16));
EXPECT_FP_EQ(0.0f16, LIBC_NAMESPACE::shared::lgammaf16(1.0f16));
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 8f1a543de0a5e..6d6c9c1a7c67e 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -2488,6 +2488,17 @@ add_fp_unittest(
libc.src.math.log10p1f16
)
+add_fp_unittest(
+ log1pf16_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ log1pf16_test.cpp
+ DEPENDS
+ libc.src.math.log1pf16
+)
+
add_fp_unittest(
log2p1f16_test
NEED_MPFR
diff --git a/libc/test/src/math/log1pf16_test.cpp b/libc/test/src/math/log1pf16_test.cpp
new file mode 100644
index 0000000000000..e671aa670fece
--- /dev/null
+++ b/libc/test/src/math/log1pf16_test.cpp
@@ -0,0 +1,49 @@
+//===-- Exhaustive test for log1pf16 --------------------------------------===//
+//
+// 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/__support/macros/optimization.h"
+#include "src/math/log1pf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#define TOLERANCE 1
+#else
+#define TOLERANCE 0
+#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+
+using LlvmLibcLog1pf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// Range: [0, Inf];
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7c00U;
+
+// Range: [-1, 0];
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xbc00U;
+
+TEST_F(LlvmLibcLog1pf16Test, PositiveRange) {
+ for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+ float16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log1p, x,
+ LIBC_NAMESPACE::log1pf16(x),
+ TOLERANCE + 0.5);
+ }
+}
+
+TEST_F(LlvmLibcLog1pf16Test, NegativeRange) {
+ for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+ float16 x = FPBits(v).get_val();
+ EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log1p, x,
+ LIBC_NAMESPACE::log1pf16(x),
+ TOLERANCE + 0.5);
+ }
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index a61b854a85fb2..5da6ccb6bcb0a 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4591,6 +4591,19 @@ add_fp_unittest(
libc.src.__support.FPUtil.cast
)
+add_fp_unittest(
+ log1pf16_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ log1pf16_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.math.log1pf16
+ libc.src.__support.FPUtil.cast
+)
+
add_fp_unittest(
log2p1f16_test
SUITE
diff --git a/libc/test/src/math/smoke/log1pf16_test.cpp b/libc/test/src/math/smoke/log1pf16_test.cpp
new file mode 100644
index 0000000000000..da0a0653981f2
--- /dev/null
+++ b/libc/test/src/math/smoke/log1pf16_test.cpp
@@ -0,0 +1,48 @@
+//===-- Unittests for log1pf16 --------------------------------------------===//
+//
+// 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 "hdr/fenv_macros.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/math/log1pf16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcLog1pf16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcLog1pf16Test, SpecialNumbers) {
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::log1pf16(aNaN));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::log1pf16(sNaN),
+ FE_INVALID);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::log1pf16(inf));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::log1pf16(neg_inf));
+ EXPECT_MATH_ERRNO(EDOM);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::log1pf16(zero));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::log1pf16(neg_zero));
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_WITH_EXCEPTION_ALL_ROUNDING(
+ neg_inf,
+ LIBC_NAMESPACE::log1pf16(LIBC_NAMESPACE::fputil::cast<float16>(-1.0)),
+ FE_DIVBYZERO);
+ EXPECT_MATH_ERRNO(0);
+
+ EXPECT_FP_EQ_ALL_ROUNDING(
+ aNaN,
+ LIBC_NAMESPACE::log1pf16(LIBC_NAMESPACE::fputil::cast<float16>(-2.0)));
+ 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 751096294f26f..ec952d0e58218 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -9912,6 +9912,27 @@ libc_support_library(
],
)
+libc_support_library(
+ name = "__support_math_log1pf16",
+ hdrs = ["src/__support/math/log1pf16.h"],
+ deps = [
+ ":__support_common",
+ ":__support_fputil_cast",
+ ":__support_fputil_except_value_utils",
+ ":__support_fputil_fenv_impl",
+ ":__support_fputil_fp_bits",
+ ":__support_fputil_multiply_add",
+ ":__support_fputil_polyeval",
+ ":__support_macros_config",
+ ":__support_macros_optimization",
+ ":__support_macros_properties_cpu_features",
+ ":__support_math_expxf16_utils",
+ ":hdr_errno_macros",
+ ":hdr_fenv_macros",
+ ":llvm_libc_macros_float16_macros",
+ ],
+)
+
libc_support_library(
name = "__support_math_log2p1f16",
hdrs = ["src/__support/math/log2p1f16.h"],
@@ -13741,6 +13762,13 @@ libc_math_function(
],
)
+libc_math_function(
+ name = "log1pf16",
+ additional_deps = [
+ ":__support_math_log1pf16",
+ ],
+)
+
libc_math_function(
name = "log2p1f16",
additional_deps = [
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel
index 8e5706c085f39..c77d5fe99d532 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel
@@ -938,6 +938,8 @@ math_mpfr_test(name = "logf16")
math_mpfr_test(name = "log2f16")
+math_mpfr_test(name = "log1pf16")
+
math_mpfr_test(name = "log2p1f16")
math_mpfr_test(name = "log10f16")
More information about the libc-commits
mailing list