[libc-commits] [libc] [libc][math][c23] Add C23 math functions ilogbf128, logbf128, and llogb(f|l|f128). (PR #82144)
via libc-commits
libc-commits at lists.llvm.org
Mon Feb 26 18:02:33 PST 2024
https://github.com/lntue updated https://github.com/llvm/llvm-project/pull/82144
>From ae80dd1a253a027aa351ec7ef3aad8c629d7952b Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Sun, 18 Feb 2024 03:20:20 +0000
Subject: [PATCH 1/4] [libc][math][c23] Add C23 math functions ilogbf128,
logbf128, and llogb(f|l|f128).
---
libc/config/gpu/entrypoints.txt | 2 +
libc/config/linux/aarch64/entrypoints.txt | 6 +
libc/config/linux/arm/entrypoints.txt | 3 +
libc/config/linux/riscv/entrypoints.txt | 6 +
libc/config/linux/x86_64/entrypoints.txt | 6 +
libc/docs/math/index.rst | 12 ++
libc/include/llvm-libc-macros/CMakeLists.txt | 2 +
libc/include/llvm-libc-macros/math-macros.h | 5 +
libc/spec/stdc.td | 7 ++
.../__support/FPUtil/ManipulationFunctions.h | 85 ++++++++-----
libc/src/__support/FPUtil/dyadic_float.h | 5 +
libc/src/math/CMakeLists.txt | 7 ++
libc/src/math/generic/CMakeLists.txt | 98 +++++++++++++--
libc/src/math/generic/ilogb.cpp | 2 +-
libc/src/math/generic/ilogbf.cpp | 2 +-
libc/src/math/generic/ilogbf128.cpp | 19 +++
libc/src/math/generic/ilogbl.cpp | 4 +-
libc/src/math/generic/llogb.cpp | 17 +++
libc/src/math/generic/llogbf.cpp | 17 +++
libc/src/math/generic/llogbf128.cpp | 19 +++
libc/src/math/generic/llogbl.cpp | 19 +++
libc/src/math/generic/logbf.cpp | 2 +-
libc/src/math/generic/logbf128.cpp | 17 +++
libc/src/math/ilogbf128.h | 20 +++
libc/src/math/llogb.h | 20 +++
libc/src/math/llogbf.h | 20 +++
libc/src/math/llogbf128.h | 20 +++
libc/src/math/llogbl.h | 20 +++
libc/src/math/logbf128.h | 20 +++
libc/test/src/math/smoke/CMakeLists.txt | 92 +++++++++++++-
libc/test/src/math/smoke/ILogbTest.h | 117 ++++++++++--------
libc/test/src/math/smoke/LogbTest.h | 8 +-
libc/test/src/math/smoke/ilogb_test.cpp | 25 +---
libc/test/src/math/smoke/ilogbf128_test.cpp | 13 ++
libc/test/src/math/smoke/ilogbf_test.cpp | 25 +---
libc/test/src/math/smoke/ilogbl_test.cpp | 25 +---
libc/test/src/math/smoke/llogb_test.cpp | 13 ++
libc/test/src/math/smoke/llogbf128_test.cpp | 13 ++
libc/test/src/math/smoke/llogbf_test.cpp | 13 ++
libc/test/src/math/smoke/llogbl_test.cpp | 13 ++
libc/test/src/math/smoke/logbf128_test.cpp | 13 ++
41 files changed, 670 insertions(+), 182 deletions(-)
create mode 100644 libc/src/math/generic/ilogbf128.cpp
create mode 100644 libc/src/math/generic/llogb.cpp
create mode 100644 libc/src/math/generic/llogbf.cpp
create mode 100644 libc/src/math/generic/llogbf128.cpp
create mode 100644 libc/src/math/generic/llogbl.cpp
create mode 100644 libc/src/math/generic/logbf128.cpp
create mode 100644 libc/src/math/ilogbf128.h
create mode 100644 libc/src/math/llogb.h
create mode 100644 libc/src/math/llogbf.h
create mode 100644 libc/src/math/llogbf128.h
create mode 100644 libc/src/math/llogbl.h
create mode 100644 libc/src/math/logbf128.h
create mode 100644 libc/test/src/math/smoke/ilogbf128_test.cpp
create mode 100644 libc/test/src/math/smoke/llogb_test.cpp
create mode 100644 libc/test/src/math/smoke/llogbf128_test.cpp
create mode 100644 libc/test/src/math/smoke/llogbf_test.cpp
create mode 100644 libc/test/src/math/smoke/llogbl_test.cpp
create mode 100644 libc/test/src/math/smoke/logbf128_test.cpp
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 5224e92bbcc589..fca5315fc4f0a8 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -239,6 +239,8 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ilogbf
libc.src.math.ldexp
libc.src.math.ldexpf
+ libc.src.math.llogb
+ libc.src.math.llogbf
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llround
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 8a6c160c099322..a6dc74101dbccb 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -341,6 +341,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ilogb
libc.src.math.ilogbf
libc.src.math.ilogbl
+ libc.src.math.llogb
+ libc.src.math.llogbf
+ libc.src.math.llogbl
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llrintl
@@ -422,7 +425,10 @@ if(LIBC_COMPILER_HAS_FLOAT128)
libc.src.math.fmaxf128
libc.src.math.fminf128
libc.src.math.frexpf128
+ libc.src.math.ilogbf128
libc.src.math.ldexpf128
+ libc.src.math.llogbf128
+ libc.src.math.logbf128
libc.src.math.roundf128
libc.src.math.sqrtf128
libc.src.math.truncf128
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 7df19049088867..2fca96c5601b08 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -217,6 +217,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ldexp
libc.src.math.ldexpf
libc.src.math.ldexpl
+ libc.src.math.llogb
+ libc.src.math.llogbf
+ libc.src.math.llogbl
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llrintl
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 5c8cc7618a9e8c..fc4d8828f4c68d 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -353,6 +353,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ldexp
libc.src.math.ldexpf
libc.src.math.ldexpl
+ libc.src.math.llogb
+ libc.src.math.llogbf
+ libc.src.math.llogbl
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llrintl
@@ -431,7 +434,10 @@ if(LIBC_COMPILER_HAS_FLOAT128)
libc.src.math.fmaxf128
libc.src.math.fminf128
libc.src.math.frexpf128
+ libc.src.math.ilogbf128
libc.src.math.ldexpf128
+ libc.src.math.llogbf128
+ libc.src.math.logbf128
libc.src.math.roundf128
libc.src.math.sqrtf128
libc.src.math.truncf128
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index cd44b5c52b58cd..c2300a2aa681a4 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -365,6 +365,9 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.ldexp
libc.src.math.ldexpf
libc.src.math.ldexpl
+ libc.src.math.llogb
+ libc.src.math.llogbf
+ libc.src.math.llogbl
libc.src.math.llrint
libc.src.math.llrintf
libc.src.math.llrintl
@@ -445,7 +448,10 @@ if(LIBC_COMPILER_HAS_FLOAT128)
libc.src.math.fmaxf128
libc.src.math.fminf128
libc.src.math.frexpf128
+ libc.src.math.ilogbf128
libc.src.math.ldexpf128
+ libc.src.math.llogbf128
+ libc.src.math.logbf128
libc.src.math.roundf128
libc.src.math.sqrtf128
libc.src.math.truncf128
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 8d584338c10f3b..80d12718edccda 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -185,6 +185,8 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ilogbl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| ilogf128 | |check| | |check| | | |check| | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ldexp | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ldexpf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
@@ -193,6 +195,14 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ldexpf128 | |check| | |check| | | |check| | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| llogb | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| llogbf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| llogbl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| llogf128 | |check| | |check| | | |check| | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| llrint | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| llrintf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
@@ -211,6 +221,8 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| logbl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| logf128 | |check| | |check| | | |check| | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| lrint | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| lrintf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index 6e0875829127e6..157b786aa7e815 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -83,6 +83,8 @@ add_macro_header(
math_macros
HDR
math-macros.h
+ DEPENDS
+ .limits_macros
)
add_macro_header(
diff --git a/libc/include/llvm-libc-macros/math-macros.h b/libc/include/llvm-libc-macros/math-macros.h
index 136670e665e6b0..54d2c57700fe04 100644
--- a/libc/include/llvm-libc-macros/math-macros.h
+++ b/libc/include/llvm-libc-macros/math-macros.h
@@ -9,6 +9,8 @@
#ifndef __LLVM_LIBC_MACROS_MATH_MACROS_H
#define __LLVM_LIBC_MACROS_MATH_MACROS_H
+#include "limits-macros.h"
+
#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
@@ -19,6 +21,9 @@
#define FP_ILOGB0 (-__INT_MAX__ - 1)
#define FP_ILOGBNAN __INT_MAX__
+#define FP_LLOGB0 (-__LONG_MAX__ - 1)
+#define FP_LLOGBNAN __LONG_MAX__
+
#define isfinite(x) __builtin_isfinite(x)
#define isinf(x) __builtin_isinf(x)
#define isnan(x) __builtin_isnan(x)
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 6b292588b6c7ae..8a1a235e4eecdc 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -414,6 +414,12 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"ilogb", RetValSpec<IntType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"ilogbf", RetValSpec<IntType>, [ArgSpec<FloatType>]>,
FunctionSpec<"ilogbl", RetValSpec<IntType>, [ArgSpec<LongDoubleType>]>,
+ GuardedFunctionSpec<"ilogbf128", RetValSpec<IntType>, [ArgSpec<Float128Type>], "LIBC_COMPILER_HAS_FLOAT128">,
+
+ FunctionSpec<"llogb", RetValSpec<LongType>, [ArgSpec<DoubleType>]>,
+ FunctionSpec<"llogbf", RetValSpec<LongType>, [ArgSpec<FloatType>]>,
+ FunctionSpec<"llogbl", RetValSpec<LongType>, [ArgSpec<LongDoubleType>]>,
+ GuardedFunctionSpec<"llogbf128", RetValSpec<LongType>, [ArgSpec<Float128Type>], "LIBC_COMPILER_HAS_FLOAT128">,
FunctionSpec<"ldexp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
FunctionSpec<"ldexpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>]>,
@@ -435,6 +441,7 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"logb", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"logbf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"logbl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
+ GuardedFunctionSpec<"logbf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_COMPILER_HAS_FLOAT128">,
FunctionSpec<"modf", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoublePtr>]>,
FunctionSpec<"modff", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatPtr>]>,
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index 9e760a28f42d75..8dd9156ce6b4b3 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -71,54 +71,79 @@ LIBC_INLINE T copysign(T x, T y) {
return xbits.get_val();
}
-template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE int ilogb(T x) {
- // TODO: Raise appropriate floating point exceptions and set errno to the
- // an appropriate error value wherever relevant.
- FPBits<T> bits(x);
- if (bits.is_zero()) {
- return FP_ILOGB0;
- } else if (bits.is_nan()) {
- return FP_ILOGBNAN;
- } else if (bits.is_inf()) {
- return INT_MAX;
+template <typename T> struct IntLogbConstants;
+
+template <> struct IntLogbConstants<int> {
+ LIBC_INLINE_VAR static constexpr int FP_LOGB0 = FP_ILOGB0;
+ LIBC_INLINE_VAR static constexpr int FP_LOGBNAN = FP_ILOGBNAN;
+ LIBC_INLINE_VAR static constexpr int T_MAX = INT_MAX;
+ LIBC_INLINE_VAR static constexpr int T_MIN = INT_MIN;
+};
+
+template <> struct IntLogbConstants<long> {
+ LIBC_INLINE_VAR static constexpr long FP_LOGB0 = FP_ILOGB0;
+ LIBC_INLINE_VAR static constexpr long FP_LOGBNAN = FP_ILOGBNAN;
+ LIBC_INLINE_VAR static constexpr long T_MAX = INT_MAX;
+ LIBC_INLINE_VAR static constexpr long T_MIN = INT_MIN;
+};
+
+template <typename T, typename U>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<U>, T>
+intlogb(U x) {
+ FPBits<U> bits(x);
+ if (LIBC_UNLIKELY(bits.is_zero() || bits.is_inf_or_nan())) {
+ set_errno_if_required(EDOM);
+ raise_except_if_required(FE_INVALID);
+
+ if (bits.is_zero())
+ return IntLogbConstants<T>::FP_LOGB0;
+ if (bits.is_nan())
+ return IntLogbConstants<T>::FP_LOGBNAN;
+ // bits is inf.
+ return IntLogbConstants<T>::T_MAX;
}
- NormalFloat<T> normal(bits);
+ DyadicFloat<FPBits<U>::STORAGE_LEN> normal(bits.get_val());
+ int exponent = normal.get_unbiased_exponent();
// The C standard does not specify the return value when an exponent is
// out of int range. However, XSI conformance required that INT_MAX or
// INT_MIN are returned.
// NOTE: It is highly unlikely that exponent will be out of int range as
// the exponent is only 15 bits wide even for the 128-bit floating point
// format.
- if (normal.exponent > INT_MAX)
- return INT_MAX;
- else if (normal.exponent < INT_MIN)
- return INT_MIN;
- else
- return normal.exponent;
+ if (LIBC_UNLIKELY(exponent > IntLogbConstants<T>::T_MAX ||
+ exponent < IntLogbConstants<T>::T_MIN)) {
+ set_errno_if_required(ERANGE);
+ raise_except_if_required(FE_INVALID);
+ return exponent ? IntLogbConstants<T>::T_MAX : IntLogbConstants<T>::T_MIN;
+ }
+
+ return static_cast<T>(exponent);
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T logb(T x) {
+LIBC_INLINE constexpr T logb(T x) {
FPBits<T> bits(x);
- if (bits.is_zero()) {
- // TODO(Floating point exception): Raise div-by-zero exception.
- // TODO(errno): POSIX requires setting errno to ERANGE.
- return FPBits<T>::inf(Sign::NEG).get_val();
- } else if (bits.is_nan()) {
- return x;
- } else if (bits.is_inf()) {
- // Return positive infinity.
+ if (LIBC_UNLIKELY(bits.is_zero() || bits.is_inf_or_nan())) {
+ if (bits.is_nan())
+ return x;
+
+ raise_except_if_required(FE_DIVBYZERO);
+
+ if (bits.is_zero()) {
+ set_errno_if_required(ERANGE);
+ return FPBits<T>::inf(Sign::NEG).get_val();
+ }
+ // bits is inf.
return FPBits<T>::inf().get_val();
}
- NormalFloat<T> normal(bits);
- return static_cast<T>(normal.exponent);
+ DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
+ return static_cast<T>(normal.get_unbiased_exponent());
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T ldexp(T x, int exp) {
+LIBC_INLINE constexpr T ldexp(T x, int exp) {
FPBits<T> bits(x);
if (LIBC_UNLIKELY((exp == 0) || bits.is_zero() || bits.is_inf_or_nan()))
return x;
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 7797c57b96fd85..14bc73433097b7 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -79,6 +79,11 @@ template <size_t Bits> struct DyadicFloat {
return *this;
}
+ // Assume that it is already normalized. Output the unbiased exponent.
+ LIBC_INLINE constexpr int get_unbiased_exponent() const {
+ return exponent + (Bits - 1);
+ }
+
// Assume that it is already normalized.
// Output is rounded correctly with respect to the current rounding mode.
template <typename T,
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 33dc1fc97c5680..efa14c42e389b3 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -157,6 +157,12 @@ add_math_entrypoint_object(hypotf)
add_math_entrypoint_object(ilogb)
add_math_entrypoint_object(ilogbf)
add_math_entrypoint_object(ilogbl)
+add_math_entrypoint_object(ilogbf128)
+
+add_math_entrypoint_object(llogb)
+add_math_entrypoint_object(llogbf)
+add_math_entrypoint_object(llogbl)
+add_math_entrypoint_object(llogbf128)
add_math_entrypoint_object(ldexp)
add_math_entrypoint_object(ldexpf)
@@ -178,6 +184,7 @@ add_math_entrypoint_object(logf)
add_math_entrypoint_object(logb)
add_math_entrypoint_object(logbf)
add_math_entrypoint_object(logbl)
+add_math_entrypoint_object(logbf128)
add_math_entrypoint_object(llrint)
add_math_entrypoint_object(llrintf)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 2ef13168bce8f0..120ada8202ab9d 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -969,10 +969,10 @@ add_entrypoint_object(
ilogb.cpp
HDRS
../ilogb.h
+ COMPILE_OPTIONS
+ -O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -981,10 +981,10 @@ add_entrypoint_object(
ilogbf.cpp
HDRS
../ilogbf.h
+ COMPILE_OPTIONS
+ -O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -993,10 +993,72 @@ add_entrypoint_object(
ilogbl.cpp
HDRS
../ilogbl.h
+ COMPILE_OPTIONS
+ -O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_entrypoint_object(
+ ilogbf128
+ SRCS
+ ilogbf128.cpp
+ HDRS
+ ../ilogbf128.h
COMPILE_OPTIONS
- -O2
+ -O3
+ DEPENDS
+ libc.src.__support.macros.properties.float
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_entrypoint_object(
+ llogb
+ SRCS
+ llogb.cpp
+ HDRS
+ ../llogb.h
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_entrypoint_object(
+ llogbf
+ SRCS
+ llogbf.cpp
+ HDRS
+ ../llogbf.h
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_entrypoint_object(
+ llogbl
+ SRCS
+ llogbl.cpp
+ HDRS
+ ../llogbl.h
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_entrypoint_object(
+ llogbf128
+ SRCS
+ llogbf128.cpp
+ HDRS
+ ../llogbf128.h
+ COMPILE_OPTIONS
+ -O3
+ DEPENDS
+ libc.src.__support.macros.properties.float
+ libc.src.__support.FPUtil.manipulation_functions
)
add_entrypoint_object(
@@ -1044,8 +1106,8 @@ add_entrypoint_object(
COMPILE_OPTIONS
-O3
DEPENDS
- libc.src.__support.macros.properties.float
- libc.src.__support.FPUtil.manipulation_functions
+ libc.src.__support.macros.properties.float
+ libc.src.__support.FPUtil.manipulation_functions
)
add_object_library(
@@ -1229,10 +1291,10 @@ add_entrypoint_object(
logb.cpp
HDRS
../logb.h
+ COMPILE_OPTIONS
+ -O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -1241,10 +1303,10 @@ add_entrypoint_object(
logbf.cpp
HDRS
../logbf.h
+ COMPILE_OPTIONS
+ -O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
- COMPILE_OPTIONS
- -O2
)
add_entrypoint_object(
@@ -1253,10 +1315,22 @@ add_entrypoint_object(
logbl.cpp
HDRS
../logbl.h
+ COMPILE_OPTIONS
+ -O3
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_entrypoint_object(
+ logbf128
+ SRCS
+ logbf128.cpp
+ HDRS
+ ../logbf128.h
COMPILE_OPTIONS
- -O2
+ -O3
+ DEPENDS
+ libc.src.__support.FPUtil.manipulation_functions
)
add_entrypoint_object(
diff --git a/libc/src/math/generic/ilogb.cpp b/libc/src/math/generic/ilogb.cpp
index 4e5f7d9642b4aa..7e4f66970c5d3c 100644
--- a/libc/src/math/generic/ilogb.cpp
+++ b/libc/src/math/generic/ilogb.cpp
@@ -12,6 +12,6 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogb, (double x)) { return fputil::intlogb<int>(x); }
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/ilogbf.cpp b/libc/src/math/generic/ilogbf.cpp
index ca15879bc25fe5..422788cec9e04f 100644
--- a/libc/src/math/generic/ilogbf.cpp
+++ b/libc/src/math/generic/ilogbf.cpp
@@ -12,6 +12,6 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogbf, (float x)) { return fputil::intlogb<int>(x); }
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/ilogbf128.cpp b/libc/src/math/generic/ilogbf128.cpp
new file mode 100644
index 00000000000000..4049eccc5f36ba
--- /dev/null
+++ b/libc/src/math/generic/ilogbf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ilogbf128 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/ilogbf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, ilogbf128, (float128 x)) {
+ return fputil::intlogb<int>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/ilogbl.cpp b/libc/src/math/generic/ilogbl.cpp
index 4c18daab1a5358..b7f7eb40c44100 100644
--- a/libc/src/math/generic/ilogbl.cpp
+++ b/libc/src/math/generic/ilogbl.cpp
@@ -12,6 +12,8 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(int, ilogbl, (long double x)) { return fputil::ilogb(x); }
+LLVM_LIBC_FUNCTION(int, ilogbl, (long double x)) {
+ return fputil::intlogb<int>(x);
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/llogb.cpp b/libc/src/math/generic/llogb.cpp
new file mode 100644
index 00000000000000..917bc38c03792b
--- /dev/null
+++ b/libc/src/math/generic/llogb.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of llogb 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/llogb.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, llogb, (double x)) { return fputil::intlogb<long>(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/llogbf.cpp b/libc/src/math/generic/llogbf.cpp
new file mode 100644
index 00000000000000..ca1c03db5c2e4c
--- /dev/null
+++ b/libc/src/math/generic/llogbf.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of llogbf 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/llogbf.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, llogbf, (float x)) { return fputil::intlogb<long>(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/llogbf128.cpp b/libc/src/math/generic/llogbf128.cpp
new file mode 100644
index 00000000000000..5ae4af302110c7
--- /dev/null
+++ b/libc/src/math/generic/llogbf128.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of llogbf128 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/llogbf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, llogbf128, (float128 x)) {
+ return fputil::intlogb<long>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/llogbl.cpp b/libc/src/math/generic/llogbl.cpp
new file mode 100644
index 00000000000000..a092997b924497
--- /dev/null
+++ b/libc/src/math/generic/llogbl.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of llogbl 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/llogbl.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(long, llogbl, (long double x)) {
+ return fputil::intlogb<long>(x);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/logbf.cpp b/libc/src/math/generic/logbf.cpp
index 78aa33ebbf4a95..9f9f7fbcfbb884 100644
--- a/libc/src/math/generic/logbf.cpp
+++ b/libc/src/math/generic/logbf.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of logbf function ---------------------------------===//
+//===-- Implementation of logbf function ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/src/math/generic/logbf128.cpp b/libc/src/math/generic/logbf128.cpp
new file mode 100644
index 00000000000000..090433d1fb8604
--- /dev/null
+++ b/libc/src/math/generic/logbf128.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of logbf128 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/logbf128.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float128, logbf128, (float128 x)) { return fputil::logb(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/ilogbf128.h b/libc/src/math/ilogbf128.h
new file mode 100644
index 00000000000000..df1145ffc0f8ab
--- /dev/null
+++ b/libc/src/math/ilogbf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ilogbf128 ---------------------*- 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_ILOGBF128_H
+#define LLVM_LIBC_SRC_MATH_ILOGBF128_H
+
+#include "src/__support/macros/properties/float.h"
+
+namespace LIBC_NAMESPACE {
+
+int ilogbf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_ILOGBF128_H
diff --git a/libc/src/math/llogb.h b/libc/src/math/llogb.h
new file mode 100644
index 00000000000000..2d95877425e568
--- /dev/null
+++ b/libc/src/math/llogb.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llogb -------------------------*- 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_LLOGB_H
+#define LLVM_LIBC_SRC_MATH_LLOGB_H
+
+#include "src/__support/macros/properties/float.h"
+
+namespace LIBC_NAMESPACE {
+
+long llogb(double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLOGB_H
diff --git a/libc/src/math/llogbf.h b/libc/src/math/llogbf.h
new file mode 100644
index 00000000000000..512e174b66ee46
--- /dev/null
+++ b/libc/src/math/llogbf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llogbf ------------------------*- 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_LLOGBF_H
+#define LLVM_LIBC_SRC_MATH_LLOGBF_H
+
+#include "src/__support/macros/properties/float.h"
+
+namespace LIBC_NAMESPACE {
+
+long llogbf(float x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLOGBF_H
diff --git a/libc/src/math/llogbf128.h b/libc/src/math/llogbf128.h
new file mode 100644
index 00000000000000..7fb74d4bbe7302
--- /dev/null
+++ b/libc/src/math/llogbf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llogbf128 ---------------------*- 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_LLOGBF128_H
+#define LLVM_LIBC_SRC_MATH_LLOGBF128_H
+
+#include "src/__support/macros/properties/float.h"
+
+namespace LIBC_NAMESPACE {
+
+long llogbf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLOGBF128_H
diff --git a/libc/src/math/llogbl.h b/libc/src/math/llogbl.h
new file mode 100644
index 00000000000000..4033100fbe3dae
--- /dev/null
+++ b/libc/src/math/llogbl.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for llogbl ------------------------*- 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_LLOGBL_H
+#define LLVM_LIBC_SRC_MATH_LLOGBL_H
+
+#include "src/__support/macros/properties/float.h"
+
+namespace LIBC_NAMESPACE {
+
+long llogbl(long double x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LLOGBL_H
diff --git a/libc/src/math/logbf128.h b/libc/src/math/logbf128.h
new file mode 100644
index 00000000000000..8baa076af1bfdb
--- /dev/null
+++ b/libc/src/math/logbf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for logbf128 ---------------------*- 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_LOGBF128_H
+#define LLVM_LIBC_SRC_MATH_LOGBF128_H
+
+#include "src/__support/macros/properties/float.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 logbf128(float128 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LOGBF128_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 0d6b33bd7d66e1..485d7c1fd71f8b 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -829,7 +829,6 @@ if(NOT LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
HDRS
ILogbTest.h
DEPENDS
- libc.include.math
libc.src.math.ilogb
libc.src.__support.CPP.limits
libc.src.__support.FPUtil.fp_bits
@@ -845,7 +844,6 @@ if(NOT LIBC_TARGET_ARCHITECTURE_IS_NVPTX)
HDRS
ILogbTest.h
DEPENDS
- libc.include.math
libc.src.math.ilogbf
libc.src.__support.CPP.limits
libc.src.__support.FPUtil.fp_bits
@@ -862,13 +860,87 @@ add_fp_unittest(
HDRS
ILogbTest.h
DEPENDS
- libc.include.math
libc.src.math.ilogbl
libc.src.__support.CPP.limits
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.manipulation_functions
)
+add_fp_unittest(
+ ilogbf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ ilogbf128_test.cpp
+ HDRS
+ ILogbTest.h
+ DEPENDS
+ libc.src.math.ilogbf128
+ libc.src.__support.CPP.limits
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
+ llogb_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ llogb_test.cpp
+ HDRS
+ ILogbTest.h
+ DEPENDS
+ libc.src.math.llogb
+ libc.src.__support.CPP.limits
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
+ llogbf_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ llogbf_test.cpp
+ HDRS
+ ILogbTest.h
+ DEPENDS
+ libc.src.math.llogbf
+ libc.src.__support.CPP.limits
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
+ llogbl_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ llogbl_test.cpp
+ HDRS
+ ILogbTest.h
+ DEPENDS
+ libc.src.math.llogbl
+ libc.src.__support.CPP.limits
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
+add_fp_unittest(
+ llogbf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ llogbf128_test.cpp
+ HDRS
+ ILogbTest.h
+ DEPENDS
+ libc.src.math.llogbf128
+ libc.src.__support.CPP.limits
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
add_fp_unittest(
ldexp_test
SUITE
@@ -936,7 +1008,6 @@ add_fp_unittest(
SRCS
logb_test.cpp
DEPENDS
- libc.include.math
libc.src.math.logb
libc.src.__support.FPUtil.manipulation_functions
)
@@ -948,7 +1019,6 @@ add_fp_unittest(
SRCS
logbf_test.cpp
DEPENDS
- libc.include.math
libc.src.math.logbf
libc.src.__support.FPUtil.manipulation_functions
)
@@ -962,11 +1032,21 @@ add_fp_unittest(
HDRS
LogbTest.h
DEPENDS
- libc.include.math
libc.src.math.logbl
libc.src.__support.FPUtil.manipulation_functions
)
+add_fp_unittest(
+ logbf128_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ logbf128_test.cpp
+ DEPENDS
+ libc.src.math.logbf128
+ libc.src.__support.FPUtil.manipulation_functions
+)
+
add_fp_unittest(
modf_test
SUITE
diff --git a/libc/test/src/math/smoke/ILogbTest.h b/libc/test/src/math/smoke/ILogbTest.h
index 3e2db33e2c0524..cbee25b139d488 100644
--- a/libc/test/src/math/smoke/ILogbTest.h
+++ b/libc/test/src/math/smoke/ILogbTest.h
@@ -13,101 +13,110 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
+template <typename OutType, typename InType>
class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
+ using FPBits = LIBC_NAMESPACE::fputil::FPBits<InType>;
+ using StorageType = typename FPBits::StorageType;
+ using Sign = LIBC_NAMESPACE::fputil::Sign;
+
public:
- template <typename T> struct ILogbFunc {
- typedef int (*Func)(T);
- };
-
- template <typename T>
- void test_special_numbers(typename ILogbFunc<T>::Func func) {
- using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
- EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::POS).get_val()));
- EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::NEG).get_val()));
- EXPECT_EQ(FP_ILOGBNAN, func(FPBits::quiet_nan().get_val()));
- EXPECT_EQ(INT_MAX, func(FPBits::inf(Sign::POS).get_val()));
- EXPECT_EQ(INT_MAX, func(FPBits::inf(Sign::NEG).get_val()));
+ typedef OutType (*Func)(InType);
+
+ void test_special_numbers(Func func) {
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::FP_LOGB0,
+ func(FPBits::zero(Sign::POS).get_val()));
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::FP_LOGB0,
+ func(FPBits::zero(Sign::NEG).get_val()));
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::FP_LOGBNAN,
+ func(FPBits::quiet_nan().get_val()));
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::T_MAX,
+ func(FPBits::inf(Sign::POS).get_val()));
+ EXPECT_EQ(LIBC_NAMESPACE::fputil::IntLogbConstants<OutType>::T_MAX,
+ func(FPBits::inf(Sign::NEG).get_val()));
}
- template <typename T>
- void test_powers_of_two(typename ILogbFunc<T>::Func func) {
- EXPECT_EQ(0, func(T(1.0)));
- EXPECT_EQ(0, func(T(-1.0)));
+ void test_powers_of_two(Func func) {
+ EXPECT_EQ(OutType(0), func(InType(1.0)));
+ EXPECT_EQ(OutType(0), func(InType(-1.0)));
- EXPECT_EQ(1, func(T(2.0)));
- EXPECT_EQ(1, func(T(-2.0)));
+ EXPECT_EQ(OutType(1), func(InType(2.0)));
+ EXPECT_EQ(OutType(1), func(InType(-2.0)));
- EXPECT_EQ(2, func(T(4.0)));
- EXPECT_EQ(2, func(T(-4.0)));
+ EXPECT_EQ(OutType(2), func(InType(4.0)));
+ EXPECT_EQ(OutType(2), func(InType(-4.0)));
- EXPECT_EQ(3, func(T(8.0)));
- EXPECT_EQ(3, func(-8.0));
+ EXPECT_EQ(OutType(3), func(InType(8.0)));
+ EXPECT_EQ(OutType(3), func(-8.0));
- EXPECT_EQ(4, func(16.0));
- EXPECT_EQ(4, func(-16.0));
+ EXPECT_EQ(OutType(4), func(16.0));
+ EXPECT_EQ(OutType(4), func(-16.0));
- EXPECT_EQ(5, func(32.0));
- EXPECT_EQ(5, func(-32.0));
+ EXPECT_EQ(OutType(5), func(32.0));
+ EXPECT_EQ(OutType(5), func(-32.0));
}
- template <typename T>
- void test_some_integers(typename ILogbFunc<T>::Func func) {
- EXPECT_EQ(1, func(T(3.0)));
- EXPECT_EQ(1, func(T(-3.0)));
+ void test_some_integers(Func func) {
+ EXPECT_EQ(OutType(1), func(InType(3.0)));
+ EXPECT_EQ(OutType(1), func(InType(-3.0)));
- EXPECT_EQ(2, func(T(7.0)));
- EXPECT_EQ(2, func(T(-7.0)));
+ EXPECT_EQ(OutType(2), func(InType(7.0)));
+ EXPECT_EQ(OutType(2), func(InType(-7.0)));
- EXPECT_EQ(3, func(T(10.0)));
- EXPECT_EQ(3, func(T(-10.0)));
+ EXPECT_EQ(OutType(3), func(InType(10.0)));
+ EXPECT_EQ(OutType(3), func(InType(-10.0)));
- EXPECT_EQ(4, func(T(31.0)));
- EXPECT_EQ(4, func(-31.0));
+ EXPECT_EQ(OutType(4), func(InType(31.0)));
+ EXPECT_EQ(OutType(4), func(-31.0));
- EXPECT_EQ(5, func(55.0));
- EXPECT_EQ(5, func(-55.0));
+ EXPECT_EQ(OutType(5), func(55.0));
+ EXPECT_EQ(OutType(5), func(-55.0));
}
- template <typename T>
- void test_subnormal_range(typename ILogbFunc<T>::Func func) {
- using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- using StorageType = typename FPBits::StorageType;
+ void test_subnormal_range(Func func) {
constexpr StorageType MIN_SUBNORMAL = FPBits::min_subnormal().uintval();
constexpr StorageType MAX_SUBNORMAL = FPBits::max_subnormal().uintval();
constexpr StorageType COUNT = 10'001;
constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
for (StorageType v = MIN_SUBNORMAL; v <= MAX_SUBNORMAL; v += STEP) {
- T x = FPBits(v).get_val();
- if (isnan(x) || isinf(x) || x == 0.0)
+ FPBits x_bits = FPBits(v);
+ if (x_bits.is_zero() || x_bits.is_inf_or_nan())
continue;
+ InType x = x_bits.get_val();
+
int exponent;
LIBC_NAMESPACE::fputil::frexp(x, exponent);
- ASSERT_EQ(exponent, func(x) + 1);
+ ASSERT_EQ(static_cast<OutType>(exponent), func(x) + OutType(1));
}
}
- template <typename T>
- void test_normal_range(typename ILogbFunc<T>::Func func) {
- using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- using StorageType = typename FPBits::StorageType;
+ void test_normal_range(Func func) {
constexpr StorageType MIN_NORMAL = FPBits::min_normal().uintval();
constexpr StorageType MAX_NORMAL = FPBits::max_normal().uintval();
constexpr StorageType COUNT = 10'001;
constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT;
for (StorageType v = MIN_NORMAL; v <= MAX_NORMAL; v += STEP) {
- T x = FPBits(v).get_val();
- if (isnan(x) || isinf(x) || x == 0.0)
+ FPBits x_bits = FPBits(v);
+ if (x_bits.is_zero() || x_bits.is_inf_or_nan())
continue;
+ InType x = x_bits.get_val();
+
int exponent;
LIBC_NAMESPACE::fputil::frexp(x, exponent);
- ASSERT_EQ(exponent, func(x) + 1);
+ ASSERT_EQ(static_cast<OutType>(exponent), func(x) + OutType(1));
}
}
};
+#define LIST_INTLOGB_TESTS(OutType, InType, Func) \
+ using LlvmLibcIntLogbTest = LlvmLibcILogbTest<OutType, InType>; \
+ TEST_F(LlvmLibcIntLogbTest, SpecialNumbers) { test_special_numbers(&Func); } \
+ TEST_F(LlvmLibcIntLogbTest, PowersOfTwo) { test_powers_of_two(&Func); } \
+ TEST_F(LlvmLibcIntLogbTest, SomeIntegers) { test_some_integers(&Func); } \
+ TEST_F(LlvmLibcIntLogbTest, SubnormalRange) { test_subnormal_range(&Func); } \
+ TEST_F(LlvmLibcIntLogbTest, NormalRange) { test_normal_range(&Func); } \
+ static_assert(true)
+
#endif // LLVM_LIBC_TEST_SRC_MATH_ILOGBTEST_H
diff --git a/libc/test/src/math/smoke/LogbTest.h b/libc/test/src/math/smoke/LogbTest.h
index e2698e2b7b81b7..01e1050b4c4f8c 100644
--- a/libc/test/src/math/smoke/LogbTest.h
+++ b/libc/test/src/math/smoke/LogbTest.h
@@ -10,8 +10,6 @@
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
-#include <math.h>
-
template <typename T> class LogbTest : public LIBC_NAMESPACE::testing::Test {
DECLARE_SPECIAL_CONSTANTS(T)
@@ -72,10 +70,12 @@ template <typename T> class LogbTest : public LIBC_NAMESPACE::testing::Test {
constexpr StorageType COUNT = 100'000;
constexpr StorageType STEP = STORAGE_MAX / COUNT;
for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
- T x = FPBits(v).get_val();
- if (isnan(x) || isinf(x) || x == 0.0l)
+ FPBits x_bits = FPBits(v);
+ if (x_bits.is_zero() || x_bits.is_inf_or_nan())
continue;
+ T x = x_bits.get_val();
+
int exponent;
LIBC_NAMESPACE::fputil::frexp(x, exponent);
ASSERT_FP_EQ(T(exponent), func(x) + T(1.0));
diff --git a/libc/test/src/math/smoke/ilogb_test.cpp b/libc/test/src/math/smoke/ilogb_test.cpp
index 7011c43386e66a..67c7939608e8b0 100644
--- a/libc/test/src/math/smoke/ilogb_test.cpp
+++ b/libc/test/src/math/smoke/ilogb_test.cpp
@@ -8,29 +8,6 @@
#include "ILogbTest.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/math/ilogb.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include <math.h>
-TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogb) {
- test_special_numbers<double>(&LIBC_NAMESPACE::ilogb);
-}
-
-TEST_F(LlvmLibcILogbTest, PowersOfTwo_ilogb) {
- test_powers_of_two<double>(&LIBC_NAMESPACE::ilogb);
-}
-
-TEST_F(LlvmLibcILogbTest, SomeIntegers_ilogb) {
- test_some_integers<double>(&LIBC_NAMESPACE::ilogb);
-}
-
-TEST_F(LlvmLibcILogbTest, SubnormalRange_ilogb) {
- test_subnormal_range<double>(&LIBC_NAMESPACE::ilogb);
-}
-
-TEST_F(LlvmLibcILogbTest, NormalRange_ilogb) {
- test_normal_range<double>(&LIBC_NAMESPACE::ilogb);
-}
+LIST_INTLOGB_TESTS(int, double, LIBC_NAMESPACE::ilogb);
diff --git a/libc/test/src/math/smoke/ilogbf128_test.cpp b/libc/test/src/math/smoke/ilogbf128_test.cpp
new file mode 100644
index 00000000000000..21ed0dd112b915
--- /dev/null
+++ b/libc/test/src/math/smoke/ilogbf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for ilogbf128 -------------------------------------------===//
+//
+// 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 "ILogbTest.h"
+
+#include "src/math/ilogbf128.h"
+
+LIST_INTLOGB_TESTS(int, float128, LIBC_NAMESPACE::ilogbf128);
diff --git a/libc/test/src/math/smoke/ilogbf_test.cpp b/libc/test/src/math/smoke/ilogbf_test.cpp
index dcff8eeb151805..68e6950cdf7255 100644
--- a/libc/test/src/math/smoke/ilogbf_test.cpp
+++ b/libc/test/src/math/smoke/ilogbf_test.cpp
@@ -8,29 +8,6 @@
#include "ILogbTest.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/math/ilogbf.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include <math.h>
-TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogbf) {
- test_special_numbers<float>(&LIBC_NAMESPACE::ilogbf);
-}
-
-TEST_F(LlvmLibcILogbTest, PowersOfTwo_ilogbf) {
- test_powers_of_two<float>(&LIBC_NAMESPACE::ilogbf);
-}
-
-TEST_F(LlvmLibcILogbTest, SomeIntegers_ilogbf) {
- test_some_integers<float>(&LIBC_NAMESPACE::ilogbf);
-}
-
-TEST_F(LlvmLibcILogbTest, SubnormalRange_ilogbf) {
- test_subnormal_range<float>(&LIBC_NAMESPACE::ilogbf);
-}
-
-TEST_F(LlvmLibcILogbTest, NormalRange_ilogbf) {
- test_normal_range<float>(&LIBC_NAMESPACE::ilogbf);
-}
+LIST_INTLOGB_TESTS(int, float, LIBC_NAMESPACE::ilogbf);
diff --git a/libc/test/src/math/smoke/ilogbl_test.cpp b/libc/test/src/math/smoke/ilogbl_test.cpp
index 29a221ad7f08f7..afc961f1686391 100644
--- a/libc/test/src/math/smoke/ilogbl_test.cpp
+++ b/libc/test/src/math/smoke/ilogbl_test.cpp
@@ -8,29 +8,6 @@
#include "ILogbTest.h"
-#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/math/ilogbl.h"
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-#include <math.h>
-TEST_F(LlvmLibcILogbTest, SpecialNumbers_ilogbl) {
- test_special_numbers<long double>(&LIBC_NAMESPACE::ilogbl);
-}
-
-TEST_F(LlvmLibcILogbTest, PowersOfTwo_ilogbl) {
- test_powers_of_two<long double>(&LIBC_NAMESPACE::ilogbl);
-}
-
-TEST_F(LlvmLibcILogbTest, SomeIntegers_ilogbl) {
- test_some_integers<long double>(&LIBC_NAMESPACE::ilogbl);
-}
-
-TEST_F(LlvmLibcILogbTest, SubnormalRange_ilogbl) {
- test_subnormal_range<long double>(&LIBC_NAMESPACE::ilogbl);
-}
-
-TEST_F(LlvmLibcILogbTest, NormalRange_ilogbl) {
- test_normal_range<long double>(&LIBC_NAMESPACE::ilogbl);
-}
+LIST_INTLOGB_TESTS(int, long double, LIBC_NAMESPACE::ilogbl);
diff --git a/libc/test/src/math/smoke/llogb_test.cpp b/libc/test/src/math/smoke/llogb_test.cpp
new file mode 100644
index 00000000000000..3bccded6c3e33e
--- /dev/null
+++ b/libc/test/src/math/smoke/llogb_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for llogb -----------------------------------------------===//
+//
+// 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 "ILogbTest.h"
+
+#include "src/math/llogb.h"
+
+LIST_INTLOGB_TESTS(long, double, LIBC_NAMESPACE::llogb);
diff --git a/libc/test/src/math/smoke/llogbf128_test.cpp b/libc/test/src/math/smoke/llogbf128_test.cpp
new file mode 100644
index 00000000000000..a1d2021d2a378a
--- /dev/null
+++ b/libc/test/src/math/smoke/llogbf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for llogbf128 -------------------------------------------===//
+//
+// 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 "ILogbTest.h"
+
+#include "src/math/llogbf128.h"
+
+LIST_INTLOGB_TESTS(long, float128, LIBC_NAMESPACE::llogbf128);
diff --git a/libc/test/src/math/smoke/llogbf_test.cpp b/libc/test/src/math/smoke/llogbf_test.cpp
new file mode 100644
index 00000000000000..60c92fbc2c4616
--- /dev/null
+++ b/libc/test/src/math/smoke/llogbf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for llogbf ----------------------------------------------===//
+//
+// 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 "ILogbTest.h"
+
+#include "src/math/llogbf.h"
+
+LIST_INTLOGB_TESTS(long, float, LIBC_NAMESPACE::llogbf);
diff --git a/libc/test/src/math/smoke/llogbl_test.cpp b/libc/test/src/math/smoke/llogbl_test.cpp
new file mode 100644
index 00000000000000..c698210fc3de1b
--- /dev/null
+++ b/libc/test/src/math/smoke/llogbl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for llogbl ----------------------------------------------===//
+//
+// 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 "ILogbTest.h"
+
+#include "src/math/llogbl.h"
+
+LIST_INTLOGB_TESTS(long, long double, LIBC_NAMESPACE::llogbl);
diff --git a/libc/test/src/math/smoke/logbf128_test.cpp b/libc/test/src/math/smoke/logbf128_test.cpp
new file mode 100644
index 00000000000000..49485f8ee71440
--- /dev/null
+++ b/libc/test/src/math/smoke/logbf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for logbf128 --------------------------------------------===//
+//
+// 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 "LogbTest.h"
+
+#include "src/math/logbf128.h"
+
+LIST_LOGB_TESTS(float128, LIBC_NAMESPACE::logbf128)
>From 6e426f6b10b120d405ea87eb84cba75b1210fd6c Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Tue, 20 Feb 2024 15:32:58 +0000
Subject: [PATCH 2/4] Use macros defined in limits-macros.h instead of
compiler's predefined macros.
---
libc/include/llvm-libc-macros/math-macros.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libc/include/llvm-libc-macros/math-macros.h b/libc/include/llvm-libc-macros/math-macros.h
index 54d2c57700fe04..0a23647319f4d3 100644
--- a/libc/include/llvm-libc-macros/math-macros.h
+++ b/libc/include/llvm-libc-macros/math-macros.h
@@ -18,11 +18,11 @@
#define INFINITY __builtin_inf()
#define NAN __builtin_nanf("")
-#define FP_ILOGB0 (-__INT_MAX__ - 1)
-#define FP_ILOGBNAN __INT_MAX__
+#define FP_ILOGB0 (-INT_MAX - 1)
+#define FP_ILOGBNAN INT_MAX
-#define FP_LLOGB0 (-__LONG_MAX__ - 1)
-#define FP_LLOGBNAN __LONG_MAX__
+#define FP_LLOGB0 (-LONG_MAX - 1)
+#define FP_LLOGBNAN LONG_MAX
#define isfinite(x) __builtin_isfinite(x)
#define isinf(x) __builtin_isinf(x)
@@ -30,7 +30,7 @@
#ifdef __FAST_MATH__
#define math_errhandling 0
-#elif defined __NO_MATH_ERRNO__
+#elif defined(__NO_MATH_ERRNO__)
#define math_errhandling (MATH_ERREXCEPT)
#else
#define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT)
>From 7501ad123702d27b1180d07061d2f4147074fb55 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Tue, 20 Feb 2024 15:38:10 +0000
Subject: [PATCH 3/4] Fix wrong min/max constants from copy-paste.
---
libc/src/__support/FPUtil/ManipulationFunctions.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index 8dd9156ce6b4b3..9b45cc660c2a47 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -83,8 +83,8 @@ template <> struct IntLogbConstants<int> {
template <> struct IntLogbConstants<long> {
LIBC_INLINE_VAR static constexpr long FP_LOGB0 = FP_ILOGB0;
LIBC_INLINE_VAR static constexpr long FP_LOGBNAN = FP_ILOGBNAN;
- LIBC_INLINE_VAR static constexpr long T_MAX = INT_MAX;
- LIBC_INLINE_VAR static constexpr long T_MIN = INT_MIN;
+ LIBC_INLINE_VAR static constexpr long T_MAX = LONG_MAX;
+ LIBC_INLINE_VAR static constexpr long T_MIN = LONG_MIN;
};
template <typename T, typename U>
>From c5469705ac909d0d0745fe9c872a48be2c658b31 Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Tue, 27 Feb 2024 02:02:09 +0000
Subject: [PATCH 4/4] Address comments.
---
libc/src/__support/FPUtil/ManipulationFunctions.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index 9b45cc660c2a47..c1d57bd37c197d 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -115,7 +115,8 @@ intlogb(U x) {
exponent < IntLogbConstants<T>::T_MIN)) {
set_errno_if_required(ERANGE);
raise_except_if_required(FE_INVALID);
- return exponent ? IntLogbConstants<T>::T_MAX : IntLogbConstants<T>::T_MIN;
+ return exponent > 0 ? IntLogbConstants<T>::T_MAX
+ : IntLogbConstants<T>::T_MIN;
}
return static_cast<T>(exponent);
More information about the libc-commits
mailing list