[libc-commits] [libc] [libc][mathvec] Add loop over scalar for unary FP32 (PR #199273)
via libc-commits
libc-commits at lists.llvm.org
Sun May 24 07:03:27 PDT 2026
https://github.com/DylanFleming-arm created https://github.com/llvm/llvm-project/pull/199273
Adds all FP32 unary functions currently supported in scalar LLVM LIBM to LIBMVEC as loop over scalars.
Includes some cleanup of existing mathvec testing infrastructure
>From 3f59d92064e05d2376953f8cf601d121f42ba76e Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 15:54:16 +0000
Subject: [PATCH 01/12] Move Mathvec abi logic to header
Removed the temporary ABI symbol macro from expf to a seperate
header to be reused by other routines
---
libc/src/mathvec/CMakeLists.txt | 9 +++++++
libc/src/mathvec/abi_prefix.h | 35 +++++++++++++++++++++++++
libc/src/mathvec/generic/CMakeLists.txt | 2 +-
libc/src/mathvec/generic/expf.cpp | 23 ++--------------
4 files changed, 47 insertions(+), 22 deletions(-)
create mode 100644 libc/src/mathvec/abi_prefix.h
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index dff1dd3b70b51..0a3784bf97796 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -1,3 +1,12 @@
+add_header_library(
+ abi_prefix
+ HDRS
+ abi_prefix.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.macros.properties.cpu_features
+)
+
add_subdirectory(generic)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
add_subdirectory(${LIBC_TARGET_ARCHITECTURE})
diff --git a/libc/src/mathvec/abi_prefix.h b/libc/src/mathvec/abi_prefix.h
new file mode 100644
index 0000000000000..83994c957cc15
--- /dev/null
+++ b/libc/src/mathvec/abi_prefix.h
@@ -0,0 +1,35 @@
+//===-- VFABI symbol construction for mathvec routines ---------*- 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_MATHVEC_ABI_PREFIX_H
+#define LLVM_LIBC_MATHVEC_ABI_PREFIX_H
+
+#include "src/__support/common.h"
+#include "src/__support/macros/properties/cpu_features.h"
+
+// TODO: Implement a more intelligent solution for
+// creating ABI symbols.
+#ifndef LIBC_MATHVEC_FLOAT_VFABI_PREFIX
+#if defined(LIBC_TARGET_CPU_HAS_AVX512F)
+#define LIBC_MATHVEC_FLOAT_VFABI_PREFIX "_ZGVeN16v_"
+#elif defined(LIBC_TARGET_CPU_HAS_AVX2)
+#define LIBC_MATHVEC_FLOAT_VFABI_PREFIX "_ZGVdN8v_"
+#elif defined(LIBC_TARGET_CPU_HAS_AVX)
+#define LIBC_MATHVEC_FLOAT_VFABI_PREFIX "_ZGVcN8v_"
+#elif defined(LIBC_TARGET_CPU_HAS_SSE2)
+#define LIBC_MATHVEC_FLOAT_VFABI_PREFIX "_ZGVbN4v_"
+#elif defined(LIBC_TARGET_CPU_HAS_ARM_NEON)
+#define LIBC_MATHVEC_FLOAT_VFABI_PREFIX "_ZGVnN4v_"
+#else
+#error "Unsupported target for mathvec VFABI symbols"
+#endif
+#endif // LIBC_MATHVEC_FLOAT_VFABI_PREFIX
+
+#define LIBC_VFABI_FLOAT_SYMBOL(name) LIBC_MATHVEC_FLOAT_VFABI_PREFIX #name
+
+#endif // LLVM_LIBC_MATHVEC_ABI_PREFIX_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index d5d94d5ed56b5..9f4cb10f6699c 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -5,7 +5,7 @@ add_entrypoint_object(
HDRS
../expf.h
DEPENDS
- libc.src.__support.macros.properties.cpu_features
+ libc.src.mathvec.abi_prefix
libc.src.__support.mathvec.expf
FLAGS
ROUND_OPT
diff --git a/libc/src/mathvec/generic/expf.cpp b/libc/src/mathvec/generic/expf.cpp
index e269fa82e08f5..fc8147d1aed45 100644
--- a/libc/src/mathvec/generic/expf.cpp
+++ b/libc/src/mathvec/generic/expf.cpp
@@ -7,32 +7,13 @@
//===----------------------------------------------------------------------===//
#include "src/mathvec/expf.h"
-#include "src/__support/common.h"
-#include "src/__support/macros/properties/cpu_features.h"
#include "src/__support/mathvec/expf.h"
-
-#ifndef LIBC_MATHVEC_EXPF_SYM
-#if defined(LIBC_TARGET_CPU_HAS_AVX512F)
-#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVeN16v_"
-#elif defined(LIBC_TARGET_CPU_HAS_AVX2)
-#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVdN8v_"
-#elif defined(LIBC_TARGET_CPU_HAS_AVX)
-#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVcN8v_"
-#elif defined(LIBC_TARGET_CPU_HAS_SSE2)
-#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVbN4v_"
-#elif defined(LIBC_TARGET_CPU_HAS_ARM_NEON)
-#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVnN4v_"
-#else
-#define LIBC_MATHVEC_EXPF_SYM_PREFIX "__"
-#endif // LIBC_TARGET_CPU_HAS_*
-
-#define LIBC_MATHVEC_EXPF_SYM LIBC_MATHVEC_EXPF_SYM_PREFIX "expf"
-#endif // LIBC_MATHVEC_EXPF_SYM
+#include "src/mathvec/abi_prefix.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(cpp::simd<float>, expf, (cpp::simd<float> x),
- LIBC_MATHVEC_EXPF_SYM) {
+ LIBC_VFABI_FLOAT_SYMBOL(expf)) {
return mathvec::expf(x);
}
>From e7a1c4b834afd1c8a52dd4047befcd89734be21c Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 16:15:52 +0000
Subject: [PATCH 02/12] Cleanup mathvec testing infrastructure
Created UnitTestWrapper.h and moved various wrappers/macros to a
header to be reused by other routines.
Added helper to the exhaustive tester to search all fp32 bit
patterns
---
libc/test/src/mathvec/CMakeLists.txt | 9 ++
libc/test/src/mathvec/UnitTestWrappers.h | 98 +++++++++++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 1 +
.../src/mathvec/exhaustive/exhaustive_test.h | 16 +++
.../test/src/mathvec/exhaustive/expf_test.cpp | 17 +--
libc/test/src/mathvec/expf_test.cpp | 103 +++++-------------
6 files changed, 156 insertions(+), 88 deletions(-)
create mode 100644 libc/test/src/mathvec/UnitTestWrappers.h
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index 9e4ae64ebccc5..719a8dc70a061 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -1,5 +1,13 @@
add_custom_target(libc-mathvec-unittests)
+add_header_library(
+ unit_test_wrappers
+ HDRS
+ UnitTestWrappers.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+)
+
add_fp_unittest(
expf_test
SUITE
@@ -7,6 +15,7 @@ add_fp_unittest(
SRCS
expf_test.cpp
DEPENDS
+ .unit_test_wrappers
libc.src.math.expf
libc.src.mathvec.expf
libc.src.__support.FPUtil.fp_bits
diff --git a/libc/test/src/mathvec/UnitTestWrappers.h b/libc/test/src/mathvec/UnitTestWrappers.h
new file mode 100644
index 0000000000000..6c7cd53e4112e
--- /dev/null
+++ b/libc/test/src/mathvec/UnitTestWrappers.h
@@ -0,0 +1,98 @@
+//===-- Mathvec unit test wrappers -----------------------------*- 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_TEST_SRC_MATHVEC_UNITTESTWRAPPERS_H
+#define LLVM_LIBC_TEST_SRC_MATHVEC_UNITTESTWRAPPERS_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "test/UnitTest/SIMDMatcher.h"
+
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace testing {
+namespace mathvec {
+
+template <typename T> using UnaryScalarFunc = T(T);
+template <typename T> using UnaryVectorFunc = cpp::simd<T>(cpp::simd<T>);
+
+template <typename T, UnaryScalarFunc<T> ScalarFunc,
+ UnaryVectorFunc<T> VectorFunc>
+struct UnaryOp {
+ using ScalarType = T;
+ using VectorType = cpp::simd<T>;
+
+ LIBC_INLINE static VectorType eval_scalar(VectorType input) {
+ VectorType output = input;
+ constexpr size_t N = cpp::internal::native_vector_size<T>;
+ for (size_t i = 0; i < N; ++i)
+ output[i] = ScalarFunc(input[i]);
+ return output;
+ }
+
+ LIBC_INLINE static VectorType eval_vector(VectorType input) {
+ return VectorFunc(input);
+ }
+};
+
+namespace internal {
+
+template <typename Op>
+LIBC_INLINE typename Op::VectorType
+make_input(typename Op::ScalarType x, typename Op::ScalarType control) {
+ typename Op::VectorType input(x);
+ input[0] = control;
+ return input;
+}
+
+} // namespace internal
+
+template <typename Op>
+LIBC_INLINE typename Op::VectorType wrap_ref(typename Op::ScalarType x,
+ typename Op::ScalarType control) {
+ return Op::eval_scalar(internal::make_input<Op>(x, control));
+}
+
+template <typename Op>
+LIBC_INLINE typename Op::VectorType wrap_ref(typename Op::ScalarType x) {
+ return wrap_ref<Op>(x, x);
+}
+
+template <typename Op>
+LIBC_INLINE typename Op::VectorType
+wrap_vector(typename Op::ScalarType x, typename Op::ScalarType control) {
+ return Op::eval_vector(internal::make_input<Op>(x, control));
+}
+
+template <typename Op>
+LIBC_INLINE typename Op::VectorType wrap_vector(typename Op::ScalarType x) {
+ return wrap_vector<Op>(x, x);
+}
+
+// A helper macro to test a variety of cases for a given input and operation.
+// Passes in various edge cases as the control input to ensure that vectorized
+// implementations behaves correctly across different input types.
+#define TEST_VARIED_CASES(x, Op) \
+ do { \
+ EXPECT_SIMD_EQ(wrap_ref<Op>((x), -(x)), wrap_vector<Op>((x), -(x))); \
+ EXPECT_SIMD_EQ(wrap_ref<Op>(-(x), (x)), wrap_vector<Op>(-(x), (x))); \
+ EXPECT_SIMD_EQ(wrap_ref<Op>((x), aNaN), wrap_vector<Op>((x), aNaN)); \
+ EXPECT_SIMD_EQ(wrap_ref<Op>((x), inf), wrap_vector<Op>((x), inf)); \
+ EXPECT_SIMD_EQ(wrap_ref<Op>((x), neg_inf), wrap_vector<Op>((x), neg_inf)); \
+ EXPECT_SIMD_EQ(wrap_ref<Op>((x), 0.0), wrap_vector<Op>((x), 0.0)); \
+ EXPECT_SIMD_EQ(wrap_ref<Op>((x), -0.0), wrap_vector<Op>((x), -0.0)); \
+ EXPECT_SIMD_EQ(wrap_ref<Op>((x), 1.0), wrap_vector<Op>((x), 1.0)); \
+ } while (0)
+
+} // namespace mathvec
+} // namespace testing
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_TEST_SRC_MATHVEC_UNITTESTWRAPPERS_H
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index 9aa287eba1952..6a96193ff27f7 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -6,6 +6,7 @@ add_header_library(
exhaustive_test.h
DEPENDS
libc.src.__support.CPP.simd
+ libc.src.__support.CPP.limits
)
add_fp_unittest(
diff --git a/libc/test/src/mathvec/exhaustive/exhaustive_test.h b/libc/test/src/mathvec/exhaustive/exhaustive_test.h
index 1add4759b8330..ed36fd68f2565 100644
--- a/libc/test/src/mathvec/exhaustive/exhaustive_test.h
+++ b/libc/test/src/mathvec/exhaustive/exhaustive_test.h
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/simd.h"
#include "test/UnitTest/FPMatcher.h"
@@ -192,6 +193,21 @@ struct LlvmLibcExhaustiveMathvecTest
test_full_range_RD(start, stop);
test_full_range_RZ(start, stop);
}
+
+ static constexpr StorageType STORAGE_MAX =
+ LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max();
+
+ void test_full_range_RN() { test_full_range_RN(0, STORAGE_MAX); }
+
+ void test_full_range_RU() { test_full_range_RU(0, STORAGE_MAX); }
+
+ void test_full_range_RD() { test_full_range_RD(0, STORAGE_MAX); }
+
+ void test_full_range_RZ() { test_full_range_RZ(0, STORAGE_MAX); }
+
+ void test_full_range_all_roundings() {
+ test_full_range_all_roundings(0, STORAGE_MAX);
+ }
};
template <typename FloatType, ScalarUnaryOp<FloatType> ScalarFunc,
diff --git a/libc/test/src/mathvec/exhaustive/expf_test.cpp b/libc/test/src/mathvec/exhaustive/expf_test.cpp
index 80fba6eebc8e5..f0b31ec87aae8 100644
--- a/libc/test/src/mathvec/exhaustive/expf_test.cpp
+++ b/libc/test/src/mathvec/exhaustive/expf_test.cpp
@@ -15,18 +15,5 @@ using LlvmLibcExpfExhaustiveTest =
LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::expf,
LIBC_NAMESPACE::expf>;
-// Range: [0, Inf];
-static constexpr uint32_t POS_START = 0x0000'0000U;
-static constexpr uint32_t POS_STOP = 0x7fff'ffffU;
-
-TEST_F(LlvmLibcExpfExhaustiveTest, PositiveRange) {
- test_full_range_RN(POS_START, POS_STOP);
-}
-
-// Range: [-Inf, 0];
-static constexpr uint32_t NEG_START = 0xb000'0000U;
-static constexpr uint32_t NEG_STOP = 0xffff'ffffU;
-
-TEST_F(LlvmLibcExpfExhaustiveTest, NegativeRange) {
- test_full_range_RN(NEG_START, NEG_STOP);
-}
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcExpfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/expf_test.cpp b/libc/test/src/mathvec/expf_test.cpp
index d7a4e148e8acd..3ca95a566cf83 100644
--- a/libc/test/src/mathvec/expf_test.cpp
+++ b/libc/test/src/mathvec/expf_test.cpp
@@ -11,121 +11,78 @@
#include "src/__support/FPUtil/FPBits.h"
#include "src/math/expf.h"
#include "src/mathvec/expf.h"
-#include "test/UnitTest/SIMDMatcher.h"
#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
#include "hdr/stdint_proxy.h"
using LlvmLibcVecExpfTest = LIBC_NAMESPACE::testing::FPTest<float>;
-// Wrappers
-
-// In order to test vector we can either duplicate a scalar input
-// or do something more elaborate. In any case that requires a wrapper
-// since the function call is written in this file.
-
-// Run reference on a vector with lanes duplicated from a scalar input.
-
-// with control lane
-static LIBC_NAMESPACE::cpp::simd<float> wrap_ref_vexpf(float x, float control) {
- LIBC_NAMESPACE::cpp::simd<float> v(x);
- v[0] = control;
- constexpr size_t N = LIBC_NAMESPACE::cpp::internal::native_vector_size<float>;
- for (size_t i = 0; i < N; i++)
- v[i] = LIBC_NAMESPACE::expf(v[i]);
- return v;
-}
-
-// without control lane
-static LIBC_NAMESPACE::cpp::simd<float> wrap_ref_vexpf(float x) {
- return wrap_ref_vexpf(x, x);
-}
-
-// Run implementation on a vector with lanes duplicated from a scalar input.
-
-// with control lane
-static LIBC_NAMESPACE::cpp::simd<float> wrap_vexpf(float x, float control) {
- LIBC_NAMESPACE::cpp::simd<float> v(x);
- v[0] = control;
- return LIBC_NAMESPACE::expf(v);
-}
-
-// without control lane
-static LIBC_NAMESPACE::cpp::simd<float> wrap_vexpf(float x) {
- return wrap_vexpf(x, x);
-}
+using ExpfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::expf,
+ LIBC_NAMESPACE::expf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
TEST_F(LlvmLibcVecExpfTest, SpecialNumbers) {
- EXPECT_SIMD_EQ(LIBC_NAMESPACE::cpp::splat(aNaN), wrap_vexpf(aNaN));
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<ExpfOp>(aNaN));
- EXPECT_SIMD_EQ(LIBC_NAMESPACE::cpp::splat(inf), wrap_vexpf(inf));
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<ExpfOp>(inf));
- EXPECT_SIMD_EQ(LIBC_NAMESPACE::cpp::splat(0.0f), wrap_vexpf(neg_inf));
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<ExpfOp>(neg_inf));
- EXPECT_SIMD_EQ(LIBC_NAMESPACE::cpp::splat(1.0f), wrap_vexpf(0.0f));
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<ExpfOp>(0.0f));
- EXPECT_SIMD_EQ(LIBC_NAMESPACE::cpp::splat(1.0f), wrap_vexpf(-0.0f));
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<ExpfOp>(-0.0f));
}
TEST_F(LlvmLibcVecExpfTest, Overflow) {
- // Fails if tested with exceptions
- EXPECT_SIMD_EQ(LIBC_NAMESPACE::cpp::splat(inf),
- wrap_vexpf(FPBits(0x7f7fffffU).get_val()));
+ EXPECT_SIMD_EQ(splat(inf),
+ wrap_vector<ExpfOp>(FPBits(0x7f7fffffU).get_val()));
- EXPECT_SIMD_EQ(LIBC_NAMESPACE::cpp::splat(inf),
- wrap_vexpf(FPBits(0x42cffff8U).get_val()));
+ EXPECT_SIMD_EQ(splat(inf),
+ wrap_vector<ExpfOp>(FPBits(0x42cffff8U).get_val()));
- EXPECT_SIMD_EQ(LIBC_NAMESPACE::cpp::splat(inf),
- wrap_vexpf(FPBits(0x42d00008U).get_val()));
+ EXPECT_SIMD_EQ(splat(inf),
+ wrap_vector<ExpfOp>(FPBits(0x42d00008U).get_val()));
}
TEST_F(LlvmLibcVecExpfTest, Underflow) {
- // Passes if tested with exceptions ?
- EXPECT_SIMD_EQ_WITH_EXCEPTION(LIBC_NAMESPACE::cpp::splat(0.0f),
- wrap_vexpf(FPBits(0xff7fffffU).get_val()),
- FE_UNDERFLOW);
+ float x = FPBits(0xff7fffffU).get_val();
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<ExpfOp>(x));
- float x = FPBits(0xc2cffff8U).get_val();
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, 1.0), wrap_vexpf(x, 1.0));
+ x = FPBits(0xc2cffff8U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<ExpfOp>(x, 1.0), wrap_vector<ExpfOp>(x, 1.0));
x = FPBits(0xc2d00008U).get_val();
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, 1.0), wrap_vexpf(x, 1.0));
+ EXPECT_SIMD_EQ(wrap_ref<ExpfOp>(x, 1.0), wrap_vector<ExpfOp>(x, 1.0));
}
-// Test with inputs which are the borders of underflow/overflow but still
-// produce valid results without setting errno.
-// Is this still relevant to vector function?
TEST_F(LlvmLibcVecExpfTest, Borderline) {
float x;
x = FPBits(0x42affff8U).get_val();
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, 1.0), wrap_vexpf(x, 1.0));
+ EXPECT_SIMD_EQ(wrap_ref<ExpfOp>(x, 1.0), wrap_vector<ExpfOp>(x, 1.0));
x = FPBits(0x42b00008U).get_val();
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, 1.0), wrap_vexpf(x, 1.0));
+ EXPECT_SIMD_EQ(wrap_ref<ExpfOp>(x, 1.0), wrap_vector<ExpfOp>(x, 1.0));
x = FPBits(0xc2affff8U).get_val();
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, 1.0), wrap_vexpf(x, 1.0));
+ EXPECT_SIMD_EQ(wrap_ref<ExpfOp>(x, 1.0), wrap_vector<ExpfOp>(x, 1.0));
x = FPBits(0xc2b00008U).get_val();
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, 1.0), wrap_vexpf(x, 1.0));
+ EXPECT_SIMD_EQ(wrap_ref<ExpfOp>(x, 1.0), wrap_vector<ExpfOp>(x, 1.0));
x = FPBits(0xc236bd8cU).get_val();
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, 1.0), wrap_vexpf(x, 1.0));
+ EXPECT_SIMD_EQ(wrap_ref<ExpfOp>(x, 1.0), wrap_vector<ExpfOp>(x, 1.0));
}
TEST_F(LlvmLibcVecExpfTest, InFloatRange) {
constexpr uint32_t COUNT = 100'000;
- constexpr uint32_t STEP = UINT32_MAX / COUNT;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
float x = FPBits(v).get_val();
- if (FPBits(v).is_nan() || FPBits(v).is_inf())
- continue;
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x), wrap_vexpf(x));
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, aNaN), wrap_vexpf(x, aNaN));
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, inf), wrap_vexpf(x, inf));
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, -inf), wrap_vexpf(x, neg_inf));
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, 0.0), wrap_vexpf(x, 0.0));
- EXPECT_SIMD_EQ(wrap_ref_vexpf(x, -0.0), wrap_vexpf(x, -0.0));
+ TEST_VARIED_CASES(x, ExpfOp);
}
}
>From 26fd438d12bd45366e17a057a3ac7c0afd4da6a6 Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 17:44:59 +0000
Subject: [PATCH 03/12] Add exp2f/exp10f as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 2 +
libc/config/linux/x86_64/entrypoints.txt | 2 +
libc/src/__support/mathvec/CMakeLists.txt | 18 +++++
libc/src/__support/mathvec/exp10f.h | 34 +++++++++
libc/src/__support/mathvec/exp2f.h | 34 +++++++++
libc/src/mathvec/CMakeLists.txt | 2 +
libc/src/mathvec/exp10f.h | 21 +++++
libc/src/mathvec/exp2f.h | 21 +++++
libc/src/mathvec/generic/CMakeLists.txt | 28 +++++++
libc/src/mathvec/generic/exp10f.cpp | 20 +++++
libc/src/mathvec/generic/exp2f.cpp | 20 +++++
libc/test/src/mathvec/CMakeLists.txt | 34 +++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 32 ++++++++
.../src/mathvec/exhaustive/exp10f_test.cpp | 19 +++++
.../src/mathvec/exhaustive/exp2f_test.cpp | 19 +++++
libc/test/src/mathvec/exp10f_test.cpp | 76 +++++++++++++++++++
libc/test/src/mathvec/exp2f_test.cpp | 72 ++++++++++++++++++
17 files changed, 454 insertions(+)
create mode 100644 libc/src/__support/mathvec/exp10f.h
create mode 100644 libc/src/__support/mathvec/exp2f.h
create mode 100644 libc/src/mathvec/exp10f.h
create mode 100644 libc/src/mathvec/exp2f.h
create mode 100644 libc/src/mathvec/generic/exp10f.cpp
create mode 100644 libc/src/mathvec/generic/exp2f.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/exp10f_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/exp2f_test.cpp
create mode 100644 libc/test/src/mathvec/exp10f_test.cpp
create mode 100644 libc/test/src/mathvec/exp2f_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 35f91c18f4bfb..3724e59489ad2 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1284,6 +1284,8 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
+ libc.src.mathvec.exp2f
+ libc.src.mathvec.exp10f
libc.src.mathvec.expf
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index eda0426ff2578..04af5fe411914 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1508,6 +1508,8 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
+ libc.src.mathvec.exp2f
+ libc.src.mathvec.exp10f
libc.src.mathvec.expf
)
endif()
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index 3cd835f1f3cd1..149c4cd2280e2 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -1,5 +1,23 @@
add_header_library(common_constants HDRS common_constants.h)
+add_header_library(
+ exp2f
+ HDRS
+ exp2f.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.exp2f
+)
+
+add_header_library(
+ exp10f
+ HDRS
+ exp10f.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.exp10f
+)
+
add_header_library(
expf_utils
HDRS
diff --git a/libc/src/__support/mathvec/exp10f.h b/libc/src/__support/mathvec/exp10f.h
new file mode 100644
index 0000000000000..e47d6847f4289
--- /dev/null
+++ b/libc/src/__support/mathvec/exp10f.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD exp10f -------------------*- 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_MATHVEC_EXP10F_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP10F_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/exp10f.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> exp10f(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::exp10f(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP10F_H
diff --git a/libc/src/__support/mathvec/exp2f.h b/libc/src/__support/mathvec/exp2f.h
new file mode 100644
index 0000000000000..cdcf4646d1e4c
--- /dev/null
+++ b/libc/src/__support/mathvec/exp2f.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD exp2f --------------------*- 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_MATHVEC_EXP2F_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP2F_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/exp2f.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> exp2f(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::exp2f(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP2F_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index 0a3784bf97796..cc425d65391e3 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -49,4 +49,6 @@ function(add_vector_math_entrypoint_object name)
)
endfunction()
+add_vector_math_entrypoint_object(exp2f)
+add_vector_math_entrypoint_object(exp10f)
add_vector_math_entrypoint_object(expf)
diff --git a/libc/src/mathvec/exp10f.h b/libc/src/mathvec/exp10f.h
new file mode 100644
index 0000000000000..28cecf5318e2e
--- /dev/null
+++ b/libc/src/mathvec/exp10f.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD exp10f -------------------*- 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_MATHVEC_EXP10F_H
+#define LLVM_LIBC_SRC_MATHVEC_EXP10F_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> exp10f(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_EXP10F_H
diff --git a/libc/src/mathvec/exp2f.h b/libc/src/mathvec/exp2f.h
new file mode 100644
index 0000000000000..67617fd6648af
--- /dev/null
+++ b/libc/src/mathvec/exp2f.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD exp2f --------------------*- 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_MATHVEC_EXP2F_H
+#define LLVM_LIBC_SRC_MATHVEC_EXP2F_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> exp2f(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_EXP2F_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index 9f4cb10f6699c..423608ea4bfa5 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -1,3 +1,31 @@
+add_entrypoint_object(
+ exp2f
+ SRCS
+ exp2f.cpp
+ HDRS
+ ../exp2f.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.exp2f
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_entrypoint_object(
+ exp10f
+ SRCS
+ exp10f.cpp
+ HDRS
+ ../exp10f.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.exp10f
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
expf
SRCS
diff --git a/libc/src/mathvec/generic/exp10f.cpp b/libc/src/mathvec/generic/exp10f.cpp
new file mode 100644
index 0000000000000..aa06bfb9f9b09
--- /dev/null
+++ b/libc/src/mathvec/generic/exp10f.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD 10^x vector 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/mathvec/exp10f.h"
+#include "src/__support/mathvec/exp10f.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, exp10f, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(exp10f)) {
+ return mathvec::exp10f(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/exp2f.cpp b/libc/src/mathvec/generic/exp2f.cpp
new file mode 100644
index 0000000000000..b02d0462b0f3d
--- /dev/null
+++ b/libc/src/mathvec/generic/exp2f.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD 2^x vector 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/mathvec/exp2f.h"
+#include "src/__support/mathvec/exp2f.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, exp2f, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(exp2f)) {
+ return mathvec::exp2f(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index 719a8dc70a061..5c6fd6e6c5931 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -8,6 +8,40 @@ add_header_library(
libc.src.__support.CPP.simd
)
+add_fp_unittest(
+ exp2f_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ exp2f_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.exp2f
+ libc.src.mathvec.exp2f
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_fp_unittest(
+ exp10f_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ exp10f_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.exp10f
+ libc.src.mathvec.exp10f
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
expf_test
SUITE
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index 6a96193ff27f7..def4bc18b012c 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -9,6 +9,38 @@ add_header_library(
libc.src.__support.CPP.limits
)
+add_fp_unittest(
+ exp2f_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ exp2f_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.exp2f
+ libc.src.mathvec.exp2f
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ exp10f_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ exp10f_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.exp10f
+ libc.src.mathvec.exp10f
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
expf_test
NO_RUN_POSTBUILD
diff --git a/libc/test/src/mathvec/exhaustive/exp10f_test.cpp b/libc/test/src/mathvec/exhaustive/exp10f_test.cpp
new file mode 100644
index 0000000000000..cc4f8cac89a3a
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/exp10f_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD exp10f -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/exp10f.h"
+#include "src/mathvec/exp10f.h"
+
+using LlvmLibcExp10fExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::exp10f,
+ LIBC_NAMESPACE::exp10f>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcExp10fExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/exp2f_test.cpp b/libc/test/src/mathvec/exhaustive/exp2f_test.cpp
new file mode 100644
index 0000000000000..f7ca1573322c0
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/exp2f_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD exp2f ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/exp2f.h"
+#include "src/mathvec/exp2f.h"
+
+using LlvmLibcExp2fExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::exp2f,
+ LIBC_NAMESPACE::exp2f>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcExp2fExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exp10f_test.cpp b/libc/test/src/mathvec/exp10f_test.cpp
new file mode 100644
index 0000000000000..04d4dd375586a
--- /dev/null
+++ b/libc/test/src/mathvec/exp10f_test.cpp
@@ -0,0 +1,76 @@
+//===-- Unittests for exp10f ---------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/exp10f.h"
+#include "src/mathvec/exp10f.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecExp10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using Exp10fOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::exp10f,
+ LIBC_NAMESPACE::exp10f>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecExp10fTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Exp10fOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp10fOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Exp10fOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<Exp10fOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<Exp10fOp>(-0.0f));
+}
+
+TEST_F(LlvmLibcVecExp10fTest, Overflow) {
+ float x = FPBits(0x7f7fffffU).get_val();
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp10fOp>(x));
+
+ x = FPBits(0x421a209aU).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Exp10fOp>(x), wrap_vector<Exp10fOp>(x));
+
+ x = FPBits(0x421a209bU).get_val();
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp10fOp>(x));
+
+ x = FPBits(0x421a209cU).get_val();
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp10fOp>(x));
+}
+
+TEST_F(LlvmLibcVecExp10fTest, Underflow) {
+ float x = FPBits(0xff7fffffU).get_val();
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Exp10fOp>(x));
+
+ // Values around log10(2^-150).
+ x = FPBits(0xc2349e34U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Exp10fOp>(x, 1.0), wrap_vector<Exp10fOp>(x, 1.0));
+
+ x = FPBits(0xc2349e35U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Exp10fOp>(x, 1.0), wrap_vector<Exp10fOp>(x, 1.0));
+
+ x = FPBits(0xc2349e36U).get_val();
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Exp10fOp>(x));
+}
+
+TEST_F(LlvmLibcVecExp10fTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, Exp10fOp);
+ }
+}
diff --git a/libc/test/src/mathvec/exp2f_test.cpp b/libc/test/src/mathvec/exp2f_test.cpp
new file mode 100644
index 0000000000000..9ae32a46885f2
--- /dev/null
+++ b/libc/test/src/mathvec/exp2f_test.cpp
@@ -0,0 +1,72 @@
+//===-- Unittests for exp2f ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/exp2f.h"
+#include "src/mathvec/exp2f.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecExp2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using Exp2fOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::exp2f,
+ LIBC_NAMESPACE::exp2f>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecExp2fTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Exp2fOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp2fOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Exp2fOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<Exp2fOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<Exp2fOp>(-0.0f));
+}
+
+TEST_F(LlvmLibcVecExp2fTest, Overflow) {
+ float x = FPBits(0x7f7fffffU).get_val();
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp2fOp>(x));
+
+ x = FPBits(0x43000000U).get_val();
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp2fOp>(x));
+
+ x = FPBits(0x43000001U).get_val();
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp2fOp>(x));
+}
+
+TEST_F(LlvmLibcVecExp2fTest, Underflow) {
+ float x = FPBits(0xff7fffffU).get_val();
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Exp2fOp>(x));
+
+ x = FPBits(0xc3158000U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Exp2fOp>(x, 1.0), wrap_vector<Exp2fOp>(x, 1.0));
+
+ x = FPBits(0xc3160000U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Exp2fOp>(x, 1.0), wrap_vector<Exp2fOp>(x, 1.0));
+
+ x = FPBits(0xc3165432U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Exp2fOp>(x, 1.0), wrap_vector<Exp2fOp>(x, 1.0));
+}
+
+TEST_F(LlvmLibcVecExp2fTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, Exp2fOp);
+ }
+}
>From daf93b781de9ea982baa80a44103520a9558e880 Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 18:24:21 +0000
Subject: [PATCH 04/12] Add expBm1f as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 4 +
libc/config/linux/x86_64/entrypoints.txt | 3 +
libc/src/__support/mathvec/CMakeLists.txt | 28 +++++
libc/src/__support/mathvec/exp10m1f.h | 34 ++++++
libc/src/__support/mathvec/exp2m1f.h | 34 ++++++
libc/src/__support/mathvec/expm1f.h | 34 ++++++
libc/src/mathvec/CMakeLists.txt | 3 +
libc/src/mathvec/exp10m1f.h | 21 ++++
libc/src/mathvec/exp2m1f.h | 21 ++++
libc/src/mathvec/expm1f.h | 21 ++++
libc/src/mathvec/generic/CMakeLists.txt | 42 +++++++
libc/src/mathvec/generic/exp10m1f.cpp | 20 ++++
libc/src/mathvec/generic/exp2m1f.cpp | 20 ++++
libc/src/mathvec/generic/expm1f.cpp | 20 ++++
libc/test/src/mathvec/CMakeLists.txt | 51 +++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 48 ++++++++
.../src/mathvec/exhaustive/exp10m1f_test.cpp | 19 ++++
.../src/mathvec/exhaustive/exp2m1f_test.cpp | 19 ++++
.../src/mathvec/exhaustive/expm1f_test.cpp | 19 ++++
libc/test/src/mathvec/exp10m1f_test.cpp | 105 ++++++++++++++++++
libc/test/src/mathvec/exp2m1f_test.cpp | 71 ++++++++++++
libc/test/src/mathvec/expm1f_test.cpp | 98 ++++++++++++++++
22 files changed, 735 insertions(+)
create mode 100644 libc/src/__support/mathvec/exp10m1f.h
create mode 100644 libc/src/__support/mathvec/exp2m1f.h
create mode 100644 libc/src/__support/mathvec/expm1f.h
create mode 100644 libc/src/mathvec/exp10m1f.h
create mode 100644 libc/src/mathvec/exp2m1f.h
create mode 100644 libc/src/mathvec/expm1f.h
create mode 100644 libc/src/mathvec/generic/exp10m1f.cpp
create mode 100644 libc/src/mathvec/generic/exp2m1f.cpp
create mode 100644 libc/src/mathvec/generic/expm1f.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/exp10m1f_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/exp2m1f_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/expm1f_test.cpp
create mode 100644 libc/test/src/mathvec/exp10m1f_test.cpp
create mode 100644 libc/test/src/mathvec/exp2m1f_test.cpp
create mode 100644 libc/test/src/mathvec/expm1f_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 3724e59489ad2..cab34768984d4 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -506,6 +506,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.exp
libc.src.math.exp10
libc.src.math.exp10f
+ libc.src.math.exp10m1f
libc.src.math.exp2
libc.src.math.exp2f
libc.src.math.exp2m1f
@@ -1285,8 +1286,11 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.exp2f
+ libc.src.mathvec.exp2m1f
libc.src.mathvec.exp10f
+ libc.src.mathvec.exp10m1f
libc.src.mathvec.expf
+ libc.src.mathvec.expm1f
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 04af5fe411914..805e8b13dd1e5 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1509,8 +1509,11 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.exp2f
+ libc.src.mathvec.exp2m1f
libc.src.mathvec.exp10f
+ libc.src.mathvec.exp10m1f
libc.src.mathvec.expf
+ libc.src.mathvec.expm1f
)
endif()
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index 149c4cd2280e2..8ce0a89351fb4 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -9,6 +9,15 @@ add_header_library(
libc.src.__support.math.exp2f
)
+add_header_library(
+ exp2m1f
+ HDRS
+ exp2m1f.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.exp2m1f
+)
+
add_header_library(
exp10f
HDRS
@@ -18,6 +27,15 @@ add_header_library(
libc.src.__support.math.exp10f
)
+add_header_library(
+ exp10m1f
+ HDRS
+ exp10m1f.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.exp10m1f
+)
+
add_header_library(
expf_utils
HDRS
@@ -37,3 +55,13 @@ add_header_library(
libc.src.__support.FPUtil.fp_bits
libc.src.__support.common
)
+
+
+add_header_library(
+ expm1f
+ HDRS
+ expm1f.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.expm1f
+)
\ No newline at end of file
diff --git a/libc/src/__support/mathvec/exp10m1f.h b/libc/src/__support/mathvec/exp10m1f.h
new file mode 100644
index 0000000000000..4602426ffe5a7
--- /dev/null
+++ b/libc/src/__support/mathvec/exp10m1f.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD exp10m1f -----------------*- 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_MATHVEC_EXP10M1F_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP10M1F_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/exp10m1f.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> exp10m1f(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::exp10m1f(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP10M1F_H
diff --git a/libc/src/__support/mathvec/exp2m1f.h b/libc/src/__support/mathvec/exp2m1f.h
new file mode 100644
index 0000000000000..e4abaa0b5b463
--- /dev/null
+++ b/libc/src/__support/mathvec/exp2m1f.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD exp2m1f ------------------*- 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_MATHVEC_EXP2M1F_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP2M1F_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/exp2m1f.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> exp2m1f(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::exp2m1f(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP2M1F_H
diff --git a/libc/src/__support/mathvec/expm1f.h b/libc/src/__support/mathvec/expm1f.h
new file mode 100644
index 0000000000000..29e0d0dd952e9
--- /dev/null
+++ b/libc/src/__support/mathvec/expm1f.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD expm1f -------------------*- 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_MATHVEC_EXPM1F_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXPM1F_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/expm1f.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> expm1f(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::expm1f(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXPM1F_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index cc425d65391e3..5a8f0fd9f399e 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -50,5 +50,8 @@ function(add_vector_math_entrypoint_object name)
endfunction()
add_vector_math_entrypoint_object(exp2f)
+add_vector_math_entrypoint_object(exp2m1f)
add_vector_math_entrypoint_object(exp10f)
+add_vector_math_entrypoint_object(exp10m1f)
add_vector_math_entrypoint_object(expf)
+add_vector_math_entrypoint_object(expm1f)
diff --git a/libc/src/mathvec/exp10m1f.h b/libc/src/mathvec/exp10m1f.h
new file mode 100644
index 0000000000000..3f0d327002620
--- /dev/null
+++ b/libc/src/mathvec/exp10m1f.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD exp10m1f -----------------*- 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_MATHVEC_EXP10M1F_H
+#define LLVM_LIBC_SRC_MATHVEC_EXP10M1F_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> exp10m1f(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_EXP10M1F_H
diff --git a/libc/src/mathvec/exp2m1f.h b/libc/src/mathvec/exp2m1f.h
new file mode 100644
index 0000000000000..6ef1d25b3b823
--- /dev/null
+++ b/libc/src/mathvec/exp2m1f.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD exp2m1f ------------------*- 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_MATHVEC_EXP2M1F_H
+#define LLVM_LIBC_SRC_MATHVEC_EXP2M1F_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> exp2m1f(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_EXP2M1F_H
diff --git a/libc/src/mathvec/expm1f.h b/libc/src/mathvec/expm1f.h
new file mode 100644
index 0000000000000..96bb6b67c5136
--- /dev/null
+++ b/libc/src/mathvec/expm1f.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD expm1f -------------------*- 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_MATHVEC_EXPM1F_H
+#define LLVM_LIBC_SRC_MATHVEC_EXPM1F_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> expm1f(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_EXPM1F_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index 423608ea4bfa5..cb29fdd51807e 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -12,6 +12,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ exp2m1f
+ SRCS
+ exp2m1f.cpp
+ HDRS
+ ../exp2m1f.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.exp2m1f
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
exp10f
SRCS
@@ -26,6 +40,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ exp10m1f
+ SRCS
+ exp10m1f.cpp
+ HDRS
+ ../exp10m1f.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.exp10m1f
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
expf
SRCS
@@ -39,3 +67,17 @@ add_entrypoint_object(
ROUND_OPT
FMA_OPT
)
+
+add_entrypoint_object(
+ expm1f
+ SRCS
+ expm1f.cpp
+ HDRS
+ ../expm1f.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.expm1f
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
diff --git a/libc/src/mathvec/generic/exp10m1f.cpp b/libc/src/mathvec/generic/exp10m1f.cpp
new file mode 100644
index 0000000000000..a3830332a7b4a
--- /dev/null
+++ b/libc/src/mathvec/generic/exp10m1f.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD 10^x - 1 vector 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/mathvec/exp10m1f.h"
+#include "src/__support/mathvec/exp10m1f.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, exp10m1f, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(exp10m1f)) {
+ return mathvec::exp10m1f(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/exp2m1f.cpp b/libc/src/mathvec/generic/exp2m1f.cpp
new file mode 100644
index 0000000000000..7df56802de96a
--- /dev/null
+++ b/libc/src/mathvec/generic/exp2m1f.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD 2^x - 1 vector 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/mathvec/exp2m1f.h"
+#include "src/__support/mathvec/exp2m1f.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, exp2m1f, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(exp2m1f)) {
+ return mathvec::exp2m1f(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/expm1f.cpp b/libc/src/mathvec/generic/expm1f.cpp
new file mode 100644
index 0000000000000..48a144a1f0a22
--- /dev/null
+++ b/libc/src/mathvec/generic/expm1f.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD e^x - 1 vector 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/mathvec/expm1f.h"
+#include "src/__support/mathvec/expm1f.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, expm1f, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(expm1f)) {
+ return mathvec::expm1f(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index 5c6fd6e6c5931..dfa9aead8e033 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -25,6 +25,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ exp2m1f_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ exp2m1f_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.exp2m1f
+ libc.src.mathvec.exp2m1f
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
exp10f_test
SUITE
@@ -42,6 +59,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ exp10m1f_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ exp10m1f_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.exp10m1f
+ libc.src.mathvec.exp10m1f
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
expf_test
SUITE
@@ -59,6 +93,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ expm1f_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ expm1f_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.expm1f
+ libc.src.mathvec.expm1f
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
if(NOT LLVM_LIBC_FULL_BUILD)
add_subdirectory(exhaustive)
endif()
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index def4bc18b012c..d342efca4e62f 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -25,6 +25,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ exp2m1f_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ exp2m1f_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.exp2m1f
+ libc.src.mathvec.exp2m1f
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
exp10f_test
NO_RUN_POSTBUILD
@@ -41,6 +57,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ exp10m1f_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ exp10m1f_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.exp10m1f
+ libc.src.mathvec.exp10m1f
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
expf_test
NO_RUN_POSTBUILD
@@ -56,3 +88,19 @@ add_fp_unittest(
LINK_LIBRARIES
-lpthread
)
+
+add_fp_unittest(
+ expm1f_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ expm1f_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.expm1f
+ libc.src.mathvec.expm1f
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
diff --git a/libc/test/src/mathvec/exhaustive/exp10m1f_test.cpp b/libc/test/src/mathvec/exhaustive/exp10m1f_test.cpp
new file mode 100644
index 0000000000000..48748aaaf785d
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/exp10m1f_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD exp10m1f ---------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/exp10m1f.h"
+#include "src/mathvec/exp10m1f.h"
+
+using LlvmLibcExp10m1fExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::exp10m1f,
+ LIBC_NAMESPACE::exp10m1f>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcExp10m1fExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/exp2m1f_test.cpp b/libc/test/src/mathvec/exhaustive/exp2m1f_test.cpp
new file mode 100644
index 0000000000000..41ca064fc5dd0
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/exp2m1f_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD exp2m1f ----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/exp2m1f.h"
+#include "src/mathvec/exp2m1f.h"
+
+using LlvmLibcExp2m1fExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::exp2m1f,
+ LIBC_NAMESPACE::exp2m1f>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcExp2m1fExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/expm1f_test.cpp b/libc/test/src/mathvec/exhaustive/expm1f_test.cpp
new file mode 100644
index 0000000000000..c02be03f2ca4c
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/expm1f_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD expm1f -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/expm1f.h"
+#include "src/mathvec/expm1f.h"
+
+using LlvmLibcExpm1fExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::expm1f,
+ LIBC_NAMESPACE::expm1f>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcExpm1fExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exp10m1f_test.cpp b/libc/test/src/mathvec/exp10m1f_test.cpp
new file mode 100644
index 0000000000000..9c4cb75486623
--- /dev/null
+++ b/libc/test/src/mathvec/exp10m1f_test.cpp
@@ -0,0 +1,105 @@
+//===-- Unittests for exp10m1f --------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/exp10m1f.h"
+#include "src/mathvec/exp10m1f.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecExp10m1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using Exp10m1fOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::exp10m1f,
+ LIBC_NAMESPACE::exp10m1f>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecExp10m1fTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Exp10m1fOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp10m1fOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(-1.0f), wrap_vector<Exp10m1fOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Exp10m1fOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(-0.0f), wrap_vector<Exp10m1fOp>(-0.0f));
+}
+
+TEST_F(LlvmLibcVecExp10m1fTest, TrickyInputs) {
+ constexpr LIBC_NAMESPACE::cpp::array<float, 39> INPUTS = {
+ // EXP10M1F_EXCEPTS_LO
+ 0x1.0fe54ep-11f,
+ 0x1.80e6eap-11f,
+ -0x1.2a33bcp-51f,
+ -0x0p+0f,
+ -0x1.b59e08p-31f,
+ -0x1.bf342p-12f,
+ -0x1.6207fp-11f,
+ -0x1.bd0c66p-11f,
+ -0x1.ffd84cp-10f,
+ -0x1.a74172p-9f,
+ -0x1.cb694cp-9f,
+ // EXP10M1F_EXCEPTS_HI
+ 0x1.8d31eep-8f,
+ 0x1.915fcep-8f,
+ 0x1.bcf982p-8f,
+ 0x1.99ff0ap-7f,
+ 0x1.75ea14p-6f,
+ 0x1.f81b64p-6f,
+ 0x1.fafecp+3f,
+ -0x1.3bf094p-8f,
+ -0x1.4558bcp-8f,
+ -0x1.4bb43p-8f,
+ -0x1.776cc8p-8f,
+ -0x1.f024cp-8f,
+ -0x1.f510eep-8f,
+ -0x1.0b43c4p-7f,
+ -0x1.245ee4p-7f,
+ -0x1.f9f2dap-7f,
+ -0x1.08e42p-6f,
+ -0x1.0cdc44p-5f,
+ -0x1.ca4322p-5f,
+ // Exceptional integers.
+ 8.0f,
+ 9.0f,
+ 10.0f,
+ // Overflow boundaries.
+ 0x1.344134p+5f,
+ 0x1.344136p+5f,
+ 0x1.344138p+5f,
+ // Underflow boundaries.
+ -0x1.e1a5e0p+2f,
+ -0x1.e1a5e2p+2f,
+ -0x1.e1a5e4p+2f,
+ };
+
+ for (float x : INPUTS) {
+ EXPECT_SIMD_EQ(wrap_ref<Exp10m1fOp>(x), wrap_vector<Exp10m1fOp>(x));
+ EXPECT_SIMD_EQ(wrap_ref<Exp10m1fOp>(x, inf),
+ wrap_vector<Exp10m1fOp>(x, inf));
+ EXPECT_SIMD_EQ(wrap_ref<Exp10m1fOp>(x, 0.0),
+ wrap_vector<Exp10m1fOp>(x, 0.0));
+ }
+}
+
+TEST_F(LlvmLibcVecExp10m1fTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, Exp10m1fOp);
+ }
+}
diff --git a/libc/test/src/mathvec/exp2m1f_test.cpp b/libc/test/src/mathvec/exp2m1f_test.cpp
new file mode 100644
index 0000000000000..e23ddcd7cc096
--- /dev/null
+++ b/libc/test/src/mathvec/exp2m1f_test.cpp
@@ -0,0 +1,71 @@
+//===-- Unittests for exp2m1f ---------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/exp2m1f.h"
+#include "src/mathvec/exp2m1f.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecExp2m1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using Exp2m1fOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::exp2m1f,
+ LIBC_NAMESPACE::exp2m1f>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecExp2m1fTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Exp2m1fOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Exp2m1fOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(-1.0f), wrap_vector<Exp2m1fOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Exp2m1fOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(-0.0f), wrap_vector<Exp2m1fOp>(-0.0f));
+}
+
+TEST_F(LlvmLibcVecExp2m1fTest, TrickyInputs) {
+ constexpr LIBC_NAMESPACE::cpp::array<float, 10> INPUTS = {
+ // EXP2M1F_EXCEPTS_LO
+ 0x1.36dc8ep-36,
+ 0x1.224936p-19,
+ 0x1.d16d2p-20,
+ 0x1.17949ep-14,
+ -0x1.9c3e1ep-38,
+ -0x1.4d89b4p-32,
+ -0x1.a6eac4p-10,
+ -0x1.e7526ep-6,
+ // EXP2M1F_EXCEPTS_HI
+ 0x1.16a972p-1,
+ -0x1.9f12acp-5,
+ };
+
+ for (float x : INPUTS) {
+ EXPECT_SIMD_EQ(wrap_ref<Exp2m1fOp>(x), wrap_vector<Exp2m1fOp>(x));
+ EXPECT_SIMD_EQ(wrap_ref<Exp2m1fOp>(x, inf), wrap_vector<Exp2m1fOp>(x, inf));
+ EXPECT_SIMD_EQ(wrap_ref<Exp2m1fOp>(x, 0.0), wrap_vector<Exp2m1fOp>(x, 0.0));
+ }
+}
+
+TEST_F(LlvmLibcVecExp2m1fTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, Exp2m1fOp);
+ }
+}
diff --git a/libc/test/src/mathvec/expm1f_test.cpp b/libc/test/src/mathvec/expm1f_test.cpp
new file mode 100644
index 0000000000000..832719d4e12c5
--- /dev/null
+++ b/libc/test/src/mathvec/expm1f_test.cpp
@@ -0,0 +1,98 @@
+//===-- Unittests for expm1f ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/expm1f.h"
+#include "src/mathvec/expm1f.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecExpm1fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using Expm1fOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::expm1f,
+ LIBC_NAMESPACE::expm1f>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecExpm1fTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Expm1fOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Expm1fOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(-1.0f), wrap_vector<Expm1fOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Expm1fOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(-0.0f), wrap_vector<Expm1fOp>(-0.0f));
+}
+
+TEST_F(LlvmLibcVecExpm1fTest, Overflow) {
+ float x = FPBits(0x7f7fffffU).get_val();
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Expm1fOp>(x));
+
+ x = FPBits(0x42cffff8U).get_val();
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Expm1fOp>(x));
+
+ x = FPBits(0x42d00008U).get_val();
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Expm1fOp>(x));
+}
+
+TEST_F(LlvmLibcVecExpm1fTest, Underflow) {
+ float x = FPBits(0xff7fffffU).get_val();
+ EXPECT_SIMD_EQ(splat(-1.0f), wrap_vector<Expm1fOp>(x));
+
+ x = FPBits(0xc2cffff8U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+
+ x = FPBits(0xc2d00008U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+}
+
+TEST_F(LlvmLibcVecExpm1fTest, Borderline) {
+ float x;
+
+ x = FPBits(0x42affff8U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+
+ x = FPBits(0x42b00008U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+
+ x = FPBits(0xc2affff8U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+
+ x = FPBits(0xc2b00008U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+
+ x = FPBits(0x3dc252ddU).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+
+ x = FPBits(0x3e35bec5U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+
+ x = FPBits(0x942ed494U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+
+ x = FPBits(0xbdc1c6cbU).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Expm1fOp>(x, 1.0), wrap_vector<Expm1fOp>(x, 1.0));
+}
+
+TEST_F(LlvmLibcVecExpm1fTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, Expm1fOp);
+ }
+}
>From 3803fe226816b039cfe49c8bbd8f4dae35e1147f Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 18:35:44 +0000
Subject: [PATCH 05/12] Add cosf/sinf/tanf as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 3 +
libc/config/linux/x86_64/entrypoints.txt | 3 +
libc/src/__support/mathvec/CMakeLists.txt | 27 ++++
libc/src/__support/mathvec/cosf.h | 34 +++++
libc/src/__support/mathvec/sinf.h | 34 +++++
libc/src/__support/mathvec/tanf.h | 34 +++++
libc/src/mathvec/CMakeLists.txt | 3 +
libc/src/mathvec/cosf.h | 21 +++
libc/src/mathvec/generic/CMakeLists.txt | 42 ++++++
libc/src/mathvec/generic/cosf.cpp | 20 +++
libc/src/mathvec/generic/sinf.cpp | 20 +++
libc/src/mathvec/generic/tanf.cpp | 20 +++
libc/src/mathvec/sinf.h | 21 +++
libc/src/mathvec/tanf.h | 21 +++
libc/test/src/mathvec/CMakeLists.txt | 57 ++++++++
libc/test/src/mathvec/cosf_test.cpp | 112 ++++++++++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 48 +++++++
.../test/src/mathvec/exhaustive/cosf_test.cpp | 19 +++
.../test/src/mathvec/exhaustive/sinf_test.cpp | 19 +++
.../test/src/mathvec/exhaustive/tanf_test.cpp | 19 +++
libc/test/src/mathvec/sinf_test.cpp | 104 +++++++++++++++
libc/test/src/mathvec/tanf_test.cpp | 122 ++++++++++++++++++
22 files changed, 803 insertions(+)
create mode 100644 libc/src/__support/mathvec/cosf.h
create mode 100644 libc/src/__support/mathvec/sinf.h
create mode 100644 libc/src/__support/mathvec/tanf.h
create mode 100644 libc/src/mathvec/cosf.h
create mode 100644 libc/src/mathvec/generic/cosf.cpp
create mode 100644 libc/src/mathvec/generic/sinf.cpp
create mode 100644 libc/src/mathvec/generic/tanf.cpp
create mode 100644 libc/src/mathvec/sinf.h
create mode 100644 libc/src/mathvec/tanf.h
create mode 100644 libc/test/src/mathvec/cosf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/cosf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/sinf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/tanf_test.cpp
create mode 100644 libc/test/src/mathvec/sinf_test.cpp
create mode 100644 libc/test/src/mathvec/tanf_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index cab34768984d4..f8140d302d34c 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1285,12 +1285,15 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
+ libc.src.mathvec.cosf
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
libc.src.mathvec.exp10f
libc.src.mathvec.exp10m1f
libc.src.mathvec.expf
libc.src.mathvec.expm1f
+ libc.src.mathvec.sinf
+ libc.src.mathvec.tanf
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 805e8b13dd1e5..cfbaa15ee11e6 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1508,12 +1508,15 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
+ libc.src.mathvec.cosf
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
libc.src.mathvec.exp10f
libc.src.mathvec.exp10m1f
libc.src.mathvec.expf
libc.src.mathvec.expm1f
+ libc.src.mathvec.sinf
+ libc.src.mathvec.tanf
)
endif()
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index 8ce0a89351fb4..52393fe1a7559 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -1,5 +1,14 @@
add_header_library(common_constants HDRS common_constants.h)
+add_header_library(
+ cosf
+ HDRS
+ cosf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.cosf
+)
+
add_header_library(
exp2f
HDRS
@@ -64,4 +73,22 @@ add_header_library(
DEPENDS
libc.src.__support.CPP.simd
libc.src.__support.math.expm1f
+)
+
+add_header_library(
+ sinf
+ HDRS
+ sinf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.sinf
+)
+
+add_header_library(
+ tanf
+ HDRS
+ tanf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.tanf
)
\ No newline at end of file
diff --git a/libc/src/__support/mathvec/cosf.h b/libc/src/__support/mathvec/cosf.h
new file mode 100644
index 0000000000000..d6710d6ecd42b
--- /dev/null
+++ b/libc/src/__support/mathvec/cosf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD cosf -------------------*- 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_MATHVEC_COSF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_COSF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/cosf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> cosf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::cosf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_COSF_H
diff --git a/libc/src/__support/mathvec/sinf.h b/libc/src/__support/mathvec/sinf.h
new file mode 100644
index 0000000000000..2d1cc33987c26
--- /dev/null
+++ b/libc/src/__support/mathvec/sinf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD sinf -------------------*- 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_MATHVEC_SINF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/sinf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> sinf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::sinf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINF_H
diff --git a/libc/src/__support/mathvec/tanf.h b/libc/src/__support/mathvec/tanf.h
new file mode 100644
index 0000000000000..94cef2f39532b
--- /dev/null
+++ b/libc/src/__support/mathvec/tanf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD tanf -------------------*- 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_MATHVEC_TANF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_TANF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/tanf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> tanf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::tanf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_TANF_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index 5a8f0fd9f399e..daf6f9a2f8dd6 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -49,9 +49,12 @@ function(add_vector_math_entrypoint_object name)
)
endfunction()
+add_vector_math_entrypoint_object(cosf)
add_vector_math_entrypoint_object(exp2f)
add_vector_math_entrypoint_object(exp2m1f)
add_vector_math_entrypoint_object(exp10f)
add_vector_math_entrypoint_object(exp10m1f)
add_vector_math_entrypoint_object(expf)
add_vector_math_entrypoint_object(expm1f)
+add_vector_math_entrypoint_object(sinf)
+add_vector_math_entrypoint_object(tanf)
diff --git a/libc/src/mathvec/cosf.h b/libc/src/mathvec/cosf.h
new file mode 100644
index 0000000000000..e8ccc3990479d
--- /dev/null
+++ b/libc/src/mathvec/cosf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD cosf ---------------------*- 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_MATHVEC_COSF_H
+#define LLVM_LIBC_SRC_MATHVEC_COSF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> cosf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_COSF_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index cb29fdd51807e..c87f74a0991c8 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -1,3 +1,17 @@
+add_entrypoint_object(
+ cosf
+ SRCS
+ cosf.cpp
+ HDRS
+ ../cosf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.cosf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
exp2f
SRCS
@@ -81,3 +95,31 @@ add_entrypoint_object(
ROUND_OPT
FMA_OPT
)
+
+add_entrypoint_object(
+ sinf
+ SRCS
+ sinf.cpp
+ HDRS
+ ../sinf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.sinf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_entrypoint_object(
+ tanf
+ SRCS
+ tanf.cpp
+ HDRS
+ ../tanf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.tanf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
diff --git a/libc/src/mathvec/generic/cosf.cpp b/libc/src/mathvec/generic/cosf.cpp
new file mode 100644
index 0000000000000..773d4cb88b92c
--- /dev/null
+++ b/libc/src/mathvec/generic/cosf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD cos vector 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/mathvec/cosf.h"
+#include "src/__support/mathvec/cosf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, cosf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(cosf)) {
+ return mathvec::cosf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/sinf.cpp b/libc/src/mathvec/generic/sinf.cpp
new file mode 100644
index 0000000000000..4f7d6dcfb0c41
--- /dev/null
+++ b/libc/src/mathvec/generic/sinf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD sin vector 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/mathvec/sinf.h"
+#include "src/__support/mathvec/sinf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, sinf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(sinf)) {
+ return mathvec::sinf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/tanf.cpp b/libc/src/mathvec/generic/tanf.cpp
new file mode 100644
index 0000000000000..ca5eab6a79932
--- /dev/null
+++ b/libc/src/mathvec/generic/tanf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD tan vector 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/mathvec/tanf.h"
+#include "src/__support/mathvec/tanf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, tanf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(tanf)) {
+ return mathvec::tanf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/sinf.h b/libc/src/mathvec/sinf.h
new file mode 100644
index 0000000000000..5e801410d4d46
--- /dev/null
+++ b/libc/src/mathvec/sinf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD sinf ---------------------*- 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_MATHVEC_SINF_H
+#define LLVM_LIBC_SRC_MATHVEC_SINF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> sinf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_SINF_H
diff --git a/libc/src/mathvec/tanf.h b/libc/src/mathvec/tanf.h
new file mode 100644
index 0000000000000..0e64f57dd85f3
--- /dev/null
+++ b/libc/src/mathvec/tanf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD tanf ---------------------*- 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_MATHVEC_TANF_H
+#define LLVM_LIBC_SRC_MATHVEC_TANF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> tanf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_TANF_H
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index dfa9aead8e033..a3e27c2792350 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -8,6 +8,25 @@ add_header_library(
libc.src.__support.CPP.simd
)
+add_fp_unittest(
+ cosf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ cosf_test.cpp
+ HDRS
+ ../math/sdcomp26094.h
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.cosf
+ libc.src.mathvec.cosf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
exp2f_test
SUITE
@@ -110,6 +129,44 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ sinf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ sinf_test.cpp
+ HDRS
+ ../math/sdcomp26094.h
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.sinf
+ libc.src.mathvec.sinf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_fp_unittest(
+ tanf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ tanf_test.cpp
+ HDRS
+ ../math/sdcomp26094.h
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.tanf
+ libc.src.mathvec.tanf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
if(NOT LLVM_LIBC_FULL_BUILD)
add_subdirectory(exhaustive)
endif()
diff --git a/libc/test/src/mathvec/cosf_test.cpp b/libc/test/src/mathvec/cosf_test.cpp
new file mode 100644
index 0000000000000..64e6b378882cb
--- /dev/null
+++ b/libc/test/src/mathvec/cosf_test.cpp
@@ -0,0 +1,112 @@
+//===-- Unittests for cosf ------------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/cosf.h"
+#include "src/mathvec/cosf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/math/sdcomp26094.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecCosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using CosfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::cosf,
+ LIBC_NAMESPACE::cosf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecCosfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<CosfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<CosfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<CosfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<CosfOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<CosfOp>(-0.0f));
+}
+
+// SDCOMP-26094: check cosf in the cases for which the range reducer
+// returns values furthest beyond its nominal upper bound of pi/4.
+TEST_F(LlvmLibcVecCosfTest, SDCOMP_26094) {
+ for (uint32_t v : SDCOMP26094_VALUES) {
+ float x = FPBits((v)).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<CosfOp>(x, -x), wrap_vector<CosfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecCosfTest, SpecificBitPatterns) {
+ constexpr int N = 42;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f06'0a92U, // x = pi/6
+ 0x3f3a'dc51U, // x = 0x1.75b8a2p-1f
+ 0x3f49'0fdbU, // x = pi/4
+ 0x3f86'0a92U, // x = pi/3
+ 0x3fa7'832aU, // x = 0x1.4f0654p+0f
+ 0x3fc9'0fdbU, // x = pi/2
+ 0x4017'1973U, // x = 0x1.2e32e6p+1f
+ 0x4049'0fdbU, // x = pi
+ 0x4096'cbe4U, // x = 0x1.2d97c8p+2f
+ 0x40c9'0fdbU, // x = 2*pi
+ 0x433b'7490U, // x = 0x1.76e92p+7f
+ 0x437c'e5f1U, // x = 0x1.f9cbe2p+7f
+ 0x4619'9998U, // x = 0x1.33333p+13f
+ 0x474d'246fU, // x = 0x1.9a48dep+15f
+ 0x4afd'ece4U, // x = 0x1.fbd9c8p+22f
+ 0x4c23'32e9U, // x = 0x1.4665d2p+25f
+ 0x50a3'e87fU, // x = 0x1.47d0fep+34f
+ 0x5239'47f6U, // x = 0x1.728fecp+37f
+ 0x53b1'46a6U, // x = 0x1.628d4cp+40f
+ 0x5532'5019U, // x = 0x1.64a032p+43f
+ 0x55ca'fb2aU, // x = 0x1.95f654p+44f
+ 0x588e'f060U, // x = 0x1.1de0cp+50f
+ 0x5922'aa80U, // x = 0x1.4555p+51f
+ 0x5aa4'542cU, // x = 0x1.48a858p+54f
+ 0x5c07'bcd0U, // x = 0x1.0f79ap+57f
+ 0x5ebc'fddeU, // x = 0x1.79fbbcp+62f
+ 0x5f18'b878U, // x = 0x1.3170fp+63f
+ 0x5fa6'eba7U, // x = 0x1.4dd74ep+64f
+ 0x6115'cb11U, // x = 0x1.2b9622p+67f
+ 0x61a4'0b40U, // x = 0x1.48168p+68f
+ 0x6386'134eU, // x = 0x1.0c269cp+72f
+ 0x6589'8498U, // x = 0x1.13093p+76f
+ 0x6600'0001U, // x = 0x1.000002p+77f
+ 0x664e'46e4U, // x = 0x1.9c8dc8p+77f
+ 0x66b0'14aaU, // x = 0x1.602954p+78f
+ 0x67a9'242bU, // x = 0x1.524856p+80f
+ 0x6a19'76f1U, // x = 0x1.32ede2p+85f
+ 0x6c55'da58U, // x = 0x1.abb4bp+89f
+ 0x6f79'be45U, // x = 0x1.f37c8ap+95f
+ 0x7276'69d4U, // x = 0x1.ecd3a8p+101f
+ 0x7758'4625U, // x = 0x1.b08c4ap+111f
+ 0x7bee'f5efU, // x = 0x1.ddebdep+120f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<CosfOp>(x, -x), wrap_vector<CosfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecCosfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, CosfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index d342efca4e62f..d274643cfb272 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -9,6 +9,22 @@ add_header_library(
libc.src.__support.CPP.limits
)
+add_fp_unittest(
+ cosf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ cosf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.cosf
+ libc.src.mathvec.cosf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
exp2f_test
NO_RUN_POSTBUILD
@@ -104,3 +120,35 @@ add_fp_unittest(
LINK_LIBRARIES
-lpthread
)
+
+add_fp_unittest(
+ sinf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ sinf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.sinf
+ libc.src.mathvec.sinf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ tanf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ tanf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.tanf
+ libc.src.mathvec.tanf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
diff --git a/libc/test/src/mathvec/exhaustive/cosf_test.cpp b/libc/test/src/mathvec/exhaustive/cosf_test.cpp
new file mode 100644
index 0000000000000..7fbbd8dd1f6a4
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/cosf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD cosf -------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/cosf.h"
+#include "src/mathvec/cosf.h"
+
+using LlvmLibcCosfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::cosf,
+ LIBC_NAMESPACE::cosf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcCosfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/sinf_test.cpp b/libc/test/src/mathvec/exhaustive/sinf_test.cpp
new file mode 100644
index 0000000000000..67a413eed346a
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/sinf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD sinf -------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/sinf.h"
+#include "src/mathvec/sinf.h"
+
+using LlvmLibcSinfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::sinf,
+ LIBC_NAMESPACE::sinf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcSinfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/tanf_test.cpp b/libc/test/src/mathvec/exhaustive/tanf_test.cpp
new file mode 100644
index 0000000000000..59ea65f7b8ad3
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/tanf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD tanf -------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/tanf.h"
+#include "src/mathvec/tanf.h"
+
+using LlvmLibcTanfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::tanf,
+ LIBC_NAMESPACE::tanf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcTanfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/sinf_test.cpp b/libc/test/src/mathvec/sinf_test.cpp
new file mode 100644
index 0000000000000..35ece42b0a74b
--- /dev/null
+++ b/libc/test/src/mathvec/sinf_test.cpp
@@ -0,0 +1,104 @@
+//===-- Unittests for sinf ------------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/sinf.h"
+#include "src/mathvec/sinf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/math/sdcomp26094.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecSinfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using SinfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::sinf,
+ LIBC_NAMESPACE::sinf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecSinfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SinfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SinfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SinfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<SinfOp>(0.0f));
+}
+
+// SDCOMP-26094: check sinf in the cases for which the range reducer
+// returns values furthest beyond its nominal upper bound of pi/4.
+TEST_F(LlvmLibcVecSinfTest, SDCOMP_26094) {
+ for (uint32_t v : SDCOMP26094_VALUES) {
+ float x = FPBits((v)).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<SinfOp>(x, -x), wrap_vector<SinfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecSinfTest, SpecificBitPatterns) {
+ constexpr int N = 36;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f06'0a92U, // x = pi/6
+ 0x3f3a'dc51U, // x = 0x1.75b8a2p-1f
+ 0x3f49'0fdbU, // x = pi/4
+ 0x3f86'0a92U, // x = pi/3
+ 0x3fa7'832aU, // x = 0x1.4f0654p+0f
+ 0x3fc9'0fdbU, // x = pi/2
+ 0x4017'1973U, // x = 0x1.2e32e6p+1f
+ 0x4049'0fdbU, // x = pi
+ 0x4096'cbe4U, // x = 0x1.2d97c8p+2f
+ 0x40c9'0fdbU, // x = 2*pi
+ 0x433b'7490U, // x = 0x1.76e92p+7f
+ 0x437c'e5f1U, // x = 0x1.f9cbe2p+7f
+ 0x4619'9998U, // x = 0x1.33333p+13f
+ 0x474d'246fU, // x = 0x1.9a48dep+15f
+ 0x4afd'ece4U, // x = 0x1.fbd9c8p+22f
+ 0x4c23'32e9U, // x = 0x1.4665d2p+25f
+ 0x50a3'e87fU, // x = 0x1.47d0fep+34f
+ 0x5239'47f6U, // x = 0x1.728fecp+37f
+ 0x53b1'46a6U, // x = 0x1.628d4cp+40f
+ 0x55ca'fb2aU, // x = 0x1.95f654p+44f
+ 0x588e'f060U, // x = 0x1.1de0cp+50f
+ 0x5c07'bcd0U, // x = 0x1.0f79ap+57f
+ 0x5ebc'fddeU, // x = 0x1.79fbbcp+62f
+ 0x5fa6'eba7U, // x = 0x1.4dd74ep+64f
+ 0x61a4'0b40U, // x = 0x1.48168p+68f
+ 0x6386'134eU, // x = 0x1.0c269cp+72f
+ 0x6589'8498U, // x = 0x1.13093p+76f
+ 0x6600'0001U, // x = 0x1.000002p+77f
+ 0x664e'46e4U, // x = 0x1.9c8dc8p+77f
+ 0x66b0'14aaU, // x = 0x1.602954p+78f
+ 0x67a9'242bU, // x = 0x1.524856p+80f
+ 0x6a19'76f1U, // x = 0x1.32ede2p+85f
+ 0x6c55'da58U, // x = 0x1.abb4bp+89f
+ 0x6f79'be45U, // x = 0x1.f37c8ap+95f
+ 0x7276'69d4U, // x = 0x1.ecd3a8p+101f
+ 0x7758'4625U, // x = 0x1.b08c4ap+111f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<SinfOp>(x, -x), wrap_vector<SinfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecSinfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, SinfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/tanf_test.cpp b/libc/test/src/mathvec/tanf_test.cpp
new file mode 100644
index 0000000000000..baf53257cb075
--- /dev/null
+++ b/libc/test/src/mathvec/tanf_test.cpp
@@ -0,0 +1,122 @@
+//===-- Unittests for tanf ------------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/tanf.h"
+#include "src/mathvec/tanf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/math/sdcomp26094.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecTanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using TanfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::tanf,
+ LIBC_NAMESPACE::tanf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecTanfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<TanfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<TanfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<TanfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<TanfOp>(0.0f));
+}
+
+// SDCOMP-26094: check tanf in the cases for which the range reducer
+// returns values furthest beyond its nominal upper bound of pi/4.
+TEST_F(LlvmLibcVecTanfTest, SDCOMP_26094) {
+ for (uint32_t v : SDCOMP26094_VALUES) {
+ float x = FPBits((v)).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<TanfOp>(x, -x), wrap_vector<TanfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecTanfTest, SpecificBitPatterns) {
+ constexpr int N = 54;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3a7a'8d2fU, // x = 0x1.f51a5ep-11f
+ 0x3f06'0a92U, // x = pi/6
+ 0x3f3a'dc51U, // x = 0x1.75b8a2p-1f
+ 0x3f49'0fdbU, // x = pi/4
+ 0x3f86'0a92U, // x = pi/3
+ 0x3f8a'1f62U, // x = 0x1.143ec4p+0f
+ 0x3fa7'832aU, // x = 0x1.4f0654p+0f
+ 0x3fc9'0fdbU, // x = pi/2
+ 0x4017'1973U, // x = 0x1.2e32e6p+1f
+ 0x4049'0fdbU, // x = pi
+ 0x4096'cbe4U, // x = 0x1.2d97c8p+2f
+ 0x40c9'0fdbU, // x = 2*pi
+ 0x433b'7490U, // x = 0x1.76e92p+7f
+ 0x437c'e5f1U, // x = 0x1.f9cbe2p+7f
+ 0x4619'9998U, // x = 0x1.33333p+13f
+ 0x474d'246fU, // x = 0x1.9a48dep+15f
+ 0x4afd'ece4U, // x = 0x1.fbd9c8p+22f
+ 0x4c23'32e9U, // x = 0x1.4665d2p+25f
+ 0x4d56'd355U, // x = 0x1.ada6aap+27f
+ 0x5043'1032U, // x = 0x1.862064p+33f
+ 0x50a3'e87fU, // x = 0x1.47d0fep+34f
+ 0x5239'47f6U, // x = 0x1.728fecp+37f
+ 0x531d'744cU, // x = 0x1.3ae898p+39f
+ 0x53b1'46a6U, // x = 0x1.628d4cp+40f
+ 0x5532'5019U, // x = 0x1.64a032p+43f
+ 0x55ca'fb2aU, // x = 0x1.95f654p+44f
+ 0x57d7'b0edU, // x = 0x1.af61dap+48f
+ 0x588e'f060U, // x = 0x1.1de0cp+50f
+ 0x5922'aa80U, // x = 0x1.4555p+51f
+ 0x5980'445eU, // x = 0x1.0088bcp+52f
+ 0x5aa4'542cU, // x = 0x1.48a858p+54f
+ 0x5c07'bcd0U, // x = 0x1.0f79ap+57f
+ 0x5ebc'fddeU, // x = 0x1.79fbbcp+62f
+ 0x5f18'b878U, // x = 0x1.3170fp+63f
+ 0x5fa6'eba7U, // x = 0x1.4dd74ep+64f
+ 0x6115'cb11U, // x = 0x1.2b9622p+67f
+ 0x61a4'0b40U, // x = 0x1.48168p+68f
+ 0x6386'134eU, // x = 0x1.0c269cp+72f
+ 0x63fc'86feU, // x = 0x1.f90dfcp+72f
+ 0x6589'8498U, // x = 0x1.13093p+76f
+ 0x65ee'8695U, // x = 0x1.dd0d2ap+76f
+ 0x6600'0001U, // x = 0x1.000002p+77f
+ 0x664e'46e4U, // x = 0x1.9c8dc8p+77f
+ 0x66b0'14aaU, // x = 0x1.602954p+78f
+ 0x6798'fe4fU, // x = 0x1.31fc9ep+80f
+ 0x67a9'242bU, // x = 0x1.524856p+80f
+ 0x6a19'76f1U, // x = 0x1.32ede2p+85f
+ 0x6ad3'6709U, // x = 0x1.a6ce12p+86f
+ 0x6c55'da58U, // x = 0x1.abb4bp+89f
+ 0x6f79'be45U, // x = 0x1.f37c8ap+95f
+ 0x7276'69d4U, // x = 0x1.ecd3a8p+101f
+ 0x72b5'05bbU, // x = 0x1.6a0b76p+102f
+ 0x7758'4625U, // x = 0x1.b08c4ap+111f
+ 0x7bee'f5efU, // x = 0x1.ddebdep+120f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<TanfOp>(x, -x), wrap_vector<TanfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecTanfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, TanfOp);
+ }
+}
>From 98966eb440f65289e7f18eb318115d755c1471c6 Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 18:42:59 +0000
Subject: [PATCH 06/12] Add acosf/asinf/atanf as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 3 +
libc/config/linux/x86_64/entrypoints.txt | 3 +
libc/src/__support/mathvec/CMakeLists.txt | 27 +++++++
libc/src/__support/mathvec/acosf.h | 34 +++++++++
libc/src/__support/mathvec/asinf.h | 34 +++++++++
libc/src/__support/mathvec/atanf.h | 34 +++++++++
libc/src/mathvec/CMakeLists.txt | 3 +
libc/src/mathvec/acosf.h | 21 ++++++
libc/src/mathvec/asinf.h | 21 ++++++
libc/src/mathvec/atanf.h | 21 ++++++
libc/src/mathvec/generic/CMakeLists.txt | 42 +++++++++++
libc/src/mathvec/generic/acosf.cpp | 20 +++++
libc/src/mathvec/generic/asinf.cpp | 20 +++++
libc/src/mathvec/generic/atanf.cpp | 20 +++++
libc/test/src/mathvec/CMakeLists.txt | 51 +++++++++++++
libc/test/src/mathvec/acosf_test.cpp | 73 +++++++++++++++++++
libc/test/src/mathvec/asinf_test.cpp | 72 ++++++++++++++++++
libc/test/src/mathvec/atanf_test.cpp | 67 +++++++++++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 48 ++++++++++++
.../src/mathvec/exhaustive/acosf_test.cpp | 19 +++++
.../src/mathvec/exhaustive/asinf_test.cpp | 19 +++++
.../src/mathvec/exhaustive/atanf_test.cpp | 19 +++++
22 files changed, 671 insertions(+)
create mode 100644 libc/src/__support/mathvec/acosf.h
create mode 100644 libc/src/__support/mathvec/asinf.h
create mode 100644 libc/src/__support/mathvec/atanf.h
create mode 100644 libc/src/mathvec/acosf.h
create mode 100644 libc/src/mathvec/asinf.h
create mode 100644 libc/src/mathvec/atanf.h
create mode 100644 libc/src/mathvec/generic/acosf.cpp
create mode 100644 libc/src/mathvec/generic/asinf.cpp
create mode 100644 libc/src/mathvec/generic/atanf.cpp
create mode 100644 libc/test/src/mathvec/acosf_test.cpp
create mode 100644 libc/test/src/mathvec/asinf_test.cpp
create mode 100644 libc/test/src/mathvec/atanf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/acosf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/asinf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/atanf_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index f8140d302d34c..054cf2173e79f 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1285,6 +1285,9 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
+ libc.src.mathvec.acosf
+ libc.src.mathvec.asinf
+ libc.src.mathvec.atanf
libc.src.mathvec.cosf
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index cfbaa15ee11e6..86335d4e7d0c2 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1508,6 +1508,9 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
+ libc.src.mathvec.acosf
+ libc.src.mathvec.asinf
+ libc.src.mathvec.atanf
libc.src.mathvec.cosf
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index 52393fe1a7559..d2f7525517251 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -1,5 +1,32 @@
add_header_library(common_constants HDRS common_constants.h)
+add_header_library(
+ acosf
+ HDRS
+ acosf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.acosf
+)
+
+add_header_library(
+ asinf
+ HDRS
+ asinf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.asinf
+)
+
+add_header_library(
+ atanf
+ HDRS
+ atanf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.atanf
+)
+
add_header_library(
cosf
HDRS
diff --git a/libc/src/__support/mathvec/acosf.h b/libc/src/__support/mathvec/acosf.h
new file mode 100644
index 0000000000000..41aa5409f439f
--- /dev/null
+++ b/libc/src/__support/mathvec/acosf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD acosf ------------------*- 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_MATHVEC_ACOSF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_ACOSF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/acosf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> acosf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::acosf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_ACOSF_H
diff --git a/libc/src/__support/mathvec/asinf.h b/libc/src/__support/mathvec/asinf.h
new file mode 100644
index 0000000000000..99fef9e7b661b
--- /dev/null
+++ b/libc/src/__support/mathvec/asinf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD asinf ------------------*- 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_MATHVEC_ASINF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_ASINF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/asinf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> asinf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::asinf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_ASINF_H
diff --git a/libc/src/__support/mathvec/atanf.h b/libc/src/__support/mathvec/atanf.h
new file mode 100644
index 0000000000000..2ff052fcc69ff
--- /dev/null
+++ b/libc/src/__support/mathvec/atanf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD atanf ------------------*- 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_MATHVEC_ATANF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_ATANF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/atanf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> atanf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::atanf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_ATANF_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index daf6f9a2f8dd6..c16e8a435fe89 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -49,6 +49,9 @@ function(add_vector_math_entrypoint_object name)
)
endfunction()
+add_vector_math_entrypoint_object(acosf)
+add_vector_math_entrypoint_object(asinf)
+add_vector_math_entrypoint_object(atanf)
add_vector_math_entrypoint_object(cosf)
add_vector_math_entrypoint_object(exp2f)
add_vector_math_entrypoint_object(exp2m1f)
diff --git a/libc/src/mathvec/acosf.h b/libc/src/mathvec/acosf.h
new file mode 100644
index 0000000000000..a13a544b8313d
--- /dev/null
+++ b/libc/src/mathvec/acosf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD acosf --------------------*- 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_MATHVEC_ACOSF_H
+#define LLVM_LIBC_SRC_MATHVEC_ACOSF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> acosf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_ACOSF_H
diff --git a/libc/src/mathvec/asinf.h b/libc/src/mathvec/asinf.h
new file mode 100644
index 0000000000000..92c063112f7b6
--- /dev/null
+++ b/libc/src/mathvec/asinf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD asinf --------------------*- 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_MATHVEC_ASINF_H
+#define LLVM_LIBC_SRC_MATHVEC_ASINF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> asinf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_ASINF_H
diff --git a/libc/src/mathvec/atanf.h b/libc/src/mathvec/atanf.h
new file mode 100644
index 0000000000000..39394d68dc29e
--- /dev/null
+++ b/libc/src/mathvec/atanf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD atanf --------------------*- 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_MATHVEC_ATANF_H
+#define LLVM_LIBC_SRC_MATHVEC_ATANF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> atanf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_ATANF_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index c87f74a0991c8..815beb6692ed5 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -1,3 +1,45 @@
+add_entrypoint_object(
+ acosf
+ SRCS
+ acosf.cpp
+ HDRS
+ ../acosf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.acosf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_entrypoint_object(
+ asinf
+ SRCS
+ asinf.cpp
+ HDRS
+ ../asinf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.asinf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_entrypoint_object(
+ atanf
+ SRCS
+ atanf.cpp
+ HDRS
+ ../atanf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.atanf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
cosf
SRCS
diff --git a/libc/src/mathvec/generic/acosf.cpp b/libc/src/mathvec/generic/acosf.cpp
new file mode 100644
index 0000000000000..a4dd792e7f8f4
--- /dev/null
+++ b/libc/src/mathvec/generic/acosf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD acosf vector 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/mathvec/acosf.h"
+#include "src/__support/mathvec/acosf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, acosf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(acosf)) {
+ return mathvec::acosf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/asinf.cpp b/libc/src/mathvec/generic/asinf.cpp
new file mode 100644
index 0000000000000..1b8b3a32d0a87
--- /dev/null
+++ b/libc/src/mathvec/generic/asinf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD asinf vector 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/mathvec/asinf.h"
+#include "src/__support/mathvec/asinf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, asinf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(asinf)) {
+ return mathvec::asinf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/atanf.cpp b/libc/src/mathvec/generic/atanf.cpp
new file mode 100644
index 0000000000000..3e67680e0a330
--- /dev/null
+++ b/libc/src/mathvec/generic/atanf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD atanf vector 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/mathvec/atanf.h"
+#include "src/__support/mathvec/atanf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, atanf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(atanf)) {
+ return mathvec::atanf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index a3e27c2792350..e3f54841d2891 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -8,6 +8,57 @@ add_header_library(
libc.src.__support.CPP.simd
)
+add_fp_unittest(
+ acosf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ acosf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.acosf
+ libc.src.mathvec.acosf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_fp_unittest(
+ asinf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ asinf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.asinf
+ libc.src.mathvec.asinf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_fp_unittest(
+ atanf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ atanf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.atanf
+ libc.src.mathvec.atanf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
cosf_test
SUITE
diff --git a/libc/test/src/mathvec/acosf_test.cpp b/libc/test/src/mathvec/acosf_test.cpp
new file mode 100644
index 0000000000000..e524ce5244949
--- /dev/null
+++ b/libc/test/src/mathvec/acosf_test.cpp
@@ -0,0 +1,73 @@
+//===-- Unittests for acosf -----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/acosf.h"
+#include "src/mathvec/acosf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecAcosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using AcosfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::acosf,
+ LIBC_NAMESPACE::acosf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecAcosfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcosfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcosfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcosfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(zero), wrap_vector<AcosfOp>(1.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcosfOp>(2.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcosfOp>(-2.0f));
+}
+
+TEST_F(LlvmLibcVecAcosfTest, SpecificBitPatterns) {
+ constexpr int N = 13;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f000000, // x = 0.5f
+ 0x3f3504f3, // x = sqrt(2)/2, FE_DOWNWARD
+ 0x3f3504f4, // x = sqrt(2)/2, FE_UPWARD
+ 0x3f5db3d7, // x = sqrt(3)/2, FE_DOWNWARD
+ 0x3f5db3d8, // x = sqrt(3)/2, FE_UPWARD
+ 0x3f800000, // x = 1.0f
+ 0x40000000, // x = 2.0f
+ 0x328885a3, // x = 0x1.110b46p-26
+ 0x39826222, // x = 0x1.04c444p-12
+ 0x3d09bf86, // x = 0x1.137f0cp-5f
+ 0x3de5fa1e, // x = 0x1.cbf43cp-4f
+ 0x3f083a1a, // x = 0x1.107434p-1f
+ 0x3f7741b6, // x = 0x1.ee836cp-1f
+ };
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<AcosfOp>(x, -x), wrap_vector<AcosfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecAcosfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, AcosfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/asinf_test.cpp b/libc/test/src/mathvec/asinf_test.cpp
new file mode 100644
index 0000000000000..d37bc35a01285
--- /dev/null
+++ b/libc/test/src/mathvec/asinf_test.cpp
@@ -0,0 +1,72 @@
+//===-- Unittests for asinf -----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/asinf.h"
+#include "src/mathvec/asinf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecAsinfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using AsinfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::asinf,
+ LIBC_NAMESPACE::asinf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecAsinfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<AsinfOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinfOp>(2.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinfOp>(-2.0f));
+}
+
+TEST_F(LlvmLibcVecAsinfTest, SpecificBitPatterns) {
+ constexpr int N = 11;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f000000, // x = 0.5f
+ 0x3f3504f3, // x = sqrt(2)/2, FE_DOWNWARD
+ 0x3f3504f4, // x = sqrt(2)/2, FE_UPWARD
+ 0x3f5db3d7, // x = sqrt(3)/2, FE_DOWNWARD
+ 0x3f5db3d8, // x = sqrt(3)/2, FE_UPWARD
+ 0x3f800000, // x = 1.0f
+ 0x40000000, // x = 2.0f
+ 0x3d09bf86, // x = 0x1.137f0cp-5f
+ 0x3de5fa1e, // x = 0x1.cbf43cp-4f
+ 0x3f083a1a, // x = 0x1.107434p-1f
+ 0x3f7741b6, // x = 0x1.ee836cp-1f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<AsinfOp>(x, -x), wrap_vector<AsinfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecAsinfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, AsinfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/atanf_test.cpp b/libc/test/src/mathvec/atanf_test.cpp
new file mode 100644
index 0000000000000..b800c7277c5cb
--- /dev/null
+++ b/libc/test/src/mathvec/atanf_test.cpp
@@ -0,0 +1,67 @@
+//===-- Unittests for atanf -----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/atanf.h"
+#include "src/mathvec/atanf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecAtanfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using AtanfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::atanf,
+ LIBC_NAMESPACE::atanf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecAtanfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AtanfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(0x1.921fb6p0), wrap_vector<AtanfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(-0x1.921fb6p0), wrap_vector<AtanfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<AtanfOp>(0.0f));
+}
+
+TEST_F(LlvmLibcVecAtanfTest, SpecificBitPatterns) {
+ constexpr int N = 10;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3d8d'6b23U, // x = 0x1.1ad646p-4f
+ 0x3dbb'6ac7U, // x = 0x1.76d58ep-4f
+ 0x3fee'fcfbU, // x = 0x1.ddf9f6p+0f
+ 0x3ffe'2ec1U, // x = 0x1.fc5d82p+0f
+ 0xbd8d'6b23U, // x = -0x1.1ad646p-4f
+ 0xbdbb'6ac7U, // x = -0x1.76d58ep-4f
+ 0xbfee'fcfbU, // x = -0x1.ddf9f6p+0f
+ 0xbffe'2ec1U, // x = -0x1.fc5d82p+0
+ 0x7f80'0000U, // x = +Inf
+ 0xff80'0000U, // x = -Inf
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<AtanfOp>(x, -x), wrap_vector<AtanfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecAtanfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, AtanfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index d274643cfb272..9bf3dfbd50fd4 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -9,6 +9,54 @@ add_header_library(
libc.src.__support.CPP.limits
)
+add_fp_unittest(
+ acosf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ acosf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.acosf
+ libc.src.mathvec.acosf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ asinf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ asinf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.asinf
+ libc.src.mathvec.asinf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ atanf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ atanf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.atanf
+ libc.src.mathvec.atanf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
cosf_test
NO_RUN_POSTBUILD
diff --git a/libc/test/src/mathvec/exhaustive/acosf_test.cpp b/libc/test/src/mathvec/exhaustive/acosf_test.cpp
new file mode 100644
index 0000000000000..cd5e3986a65a7
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/acosf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD acosf ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/acosf.h"
+#include "src/mathvec/acosf.h"
+
+using LlvmLibcAcosfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::acosf,
+ LIBC_NAMESPACE::acosf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcAcosfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/asinf_test.cpp b/libc/test/src/mathvec/exhaustive/asinf_test.cpp
new file mode 100644
index 0000000000000..2659872b2f07a
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/asinf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD asinf ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/asinf.h"
+#include "src/mathvec/asinf.h"
+
+using LlvmLibcAsinfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::asinf,
+ LIBC_NAMESPACE::asinf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcAsinfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/atanf_test.cpp b/libc/test/src/mathvec/exhaustive/atanf_test.cpp
new file mode 100644
index 0000000000000..5466d72356dbf
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/atanf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD atanf ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/atanf.h"
+#include "src/mathvec/atanf.h"
+
+using LlvmLibcAtanfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::atanf,
+ LIBC_NAMESPACE::atanf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcAtanfExhaustiveTest, EntireRange) { test_full_range_RN(); }
>From f49f1eb52606087bf2484fd2392a803f1e4778d6 Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 18:54:58 +0000
Subject: [PATCH 07/12] Add cospif/sinpif/tanpif as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 3 +
libc/config/linux/x86_64/entrypoints.txt | 3 +
libc/src/__support/mathvec/CMakeLists.txt | 27 ++++
libc/src/__support/mathvec/cospif.h | 34 ++++++
libc/src/__support/mathvec/sinpif.h | 34 ++++++
libc/src/__support/mathvec/tanpif.h | 34 ++++++
libc/src/mathvec/CMakeLists.txt | 3 +
libc/src/mathvec/cospif.h | 21 ++++
libc/src/mathvec/generic/CMakeLists.txt | 42 +++++++
libc/src/mathvec/generic/cospif.cpp | 20 +++
libc/src/mathvec/generic/sinpif.cpp | 20 +++
libc/src/mathvec/generic/tanpif.cpp | 20 +++
libc/src/mathvec/sinpif.h | 21 ++++
libc/src/mathvec/tanpif.h | 21 ++++
libc/test/src/mathvec/CMakeLists.txt | 57 +++++++++
libc/test/src/mathvec/cospif_test.cpp | 106 ++++++++++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 48 ++++++++
.../src/mathvec/exhaustive/cospif_test.cpp | 19 +++
.../src/mathvec/exhaustive/sinpif_test.cpp | 19 +++
.../src/mathvec/exhaustive/tanpif_test.cpp | 19 +++
libc/test/src/mathvec/sinpif_test.cpp | 102 ++++++++++++++++
libc/test/src/mathvec/tanpif_test.cpp | 115 ++++++++++++++++++
22 files changed, 788 insertions(+)
create mode 100644 libc/src/__support/mathvec/cospif.h
create mode 100644 libc/src/__support/mathvec/sinpif.h
create mode 100644 libc/src/__support/mathvec/tanpif.h
create mode 100644 libc/src/mathvec/cospif.h
create mode 100644 libc/src/mathvec/generic/cospif.cpp
create mode 100644 libc/src/mathvec/generic/sinpif.cpp
create mode 100644 libc/src/mathvec/generic/tanpif.cpp
create mode 100644 libc/src/mathvec/sinpif.h
create mode 100644 libc/src/mathvec/tanpif.h
create mode 100644 libc/test/src/mathvec/cospif_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/cospif_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/sinpif_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/tanpif_test.cpp
create mode 100644 libc/test/src/mathvec/sinpif_test.cpp
create mode 100644 libc/test/src/mathvec/tanpif_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 054cf2173e79f..29911fbdc311b 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1289,6 +1289,7 @@ if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
libc.src.mathvec.asinf
libc.src.mathvec.atanf
libc.src.mathvec.cosf
+ libc.src.mathvec.cospif
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
libc.src.mathvec.exp10f
@@ -1296,7 +1297,9 @@ if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
libc.src.mathvec.expf
libc.src.mathvec.expm1f
libc.src.mathvec.sinf
+ libc.src.mathvec.sinpif
libc.src.mathvec.tanf
+ libc.src.mathvec.tanpif
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 86335d4e7d0c2..0468152f2d3cf 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1512,6 +1512,7 @@ list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.asinf
libc.src.mathvec.atanf
libc.src.mathvec.cosf
+ libc.src.mathvec.cospif
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
libc.src.mathvec.exp10f
@@ -1519,7 +1520,9 @@ list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.expf
libc.src.mathvec.expm1f
libc.src.mathvec.sinf
+ libc.src.mathvec.sinpif
libc.src.mathvec.tanf
+ libc.src.mathvec.tanpif
)
endif()
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index d2f7525517251..e08e6fa6ebba5 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -36,6 +36,15 @@ add_header_library(
libc.src.__support.math.cosf
)
+add_header_library(
+ cospif
+ HDRS
+ cospif.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.cospif
+)
+
add_header_library(
exp2f
HDRS
@@ -111,6 +120,15 @@ add_header_library(
libc.src.__support.math.sinf
)
+add_header_library(
+ sinpif
+ HDRS
+ sinpif.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.sinpif
+)
+
add_header_library(
tanf
HDRS
@@ -118,4 +136,13 @@ add_header_library(
DEPENDS
libc.src.__support.CPP.simd
libc.src.__support.math.tanf
+)
+
+add_header_library(
+ tanpif
+ HDRS
+ tanpif.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.tanpif
)
\ No newline at end of file
diff --git a/libc/src/__support/mathvec/cospif.h b/libc/src/__support/mathvec/cospif.h
new file mode 100644
index 0000000000000..d70eacd1a4521
--- /dev/null
+++ b/libc/src/__support/mathvec/cospif.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD cospif -----------------*- 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_MATHVEC_COSPIF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_COSPIF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/cospif.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> cospif(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::cospif(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_COSPIF_H
diff --git a/libc/src/__support/mathvec/sinpif.h b/libc/src/__support/mathvec/sinpif.h
new file mode 100644
index 0000000000000..5276f39d24fc1
--- /dev/null
+++ b/libc/src/__support/mathvec/sinpif.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD sinpif -----------------*- 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_MATHVEC_SINPIF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINPIF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/sinpif.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> sinpif(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::sinpif(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINPIF_H
diff --git a/libc/src/__support/mathvec/tanpif.h b/libc/src/__support/mathvec/tanpif.h
new file mode 100644
index 0000000000000..3cafa0a02764f
--- /dev/null
+++ b/libc/src/__support/mathvec/tanpif.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD tanpif -----------------*- 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_MATHVEC_TANPIF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_TANPIF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/tanpif.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> tanpif(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::tanpif(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_TANPIF_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index c16e8a435fe89..8a2108cf2ee3f 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -53,6 +53,7 @@ add_vector_math_entrypoint_object(acosf)
add_vector_math_entrypoint_object(asinf)
add_vector_math_entrypoint_object(atanf)
add_vector_math_entrypoint_object(cosf)
+add_vector_math_entrypoint_object(cospif)
add_vector_math_entrypoint_object(exp2f)
add_vector_math_entrypoint_object(exp2m1f)
add_vector_math_entrypoint_object(exp10f)
@@ -60,4 +61,6 @@ add_vector_math_entrypoint_object(exp10m1f)
add_vector_math_entrypoint_object(expf)
add_vector_math_entrypoint_object(expm1f)
add_vector_math_entrypoint_object(sinf)
+add_vector_math_entrypoint_object(sinpif)
add_vector_math_entrypoint_object(tanf)
+add_vector_math_entrypoint_object(tanpif)
diff --git a/libc/src/mathvec/cospif.h b/libc/src/mathvec/cospif.h
new file mode 100644
index 0000000000000..196cbbfd49d65
--- /dev/null
+++ b/libc/src/mathvec/cospif.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD cospif -------------------*- 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_MATHVEC_COSPIF_H
+#define LLVM_LIBC_SRC_MATHVEC_COSPIF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> cospif(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_COSPIF_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index 815beb6692ed5..6460e0e28c03a 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -54,6 +54,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ cospif
+ SRCS
+ cospif.cpp
+ HDRS
+ ../cospif.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.cospif
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
exp2f
SRCS
@@ -152,6 +166,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ sinpif
+ SRCS
+ sinpif.cpp
+ HDRS
+ ../sinpif.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.sinpif
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
tanf
SRCS
@@ -165,3 +193,17 @@ add_entrypoint_object(
ROUND_OPT
FMA_OPT
)
+
+add_entrypoint_object(
+ tanpif
+ SRCS
+ tanpif.cpp
+ HDRS
+ ../tanpif.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.tanpif
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
diff --git a/libc/src/mathvec/generic/cospif.cpp b/libc/src/mathvec/generic/cospif.cpp
new file mode 100644
index 0000000000000..17e07ea6ae034
--- /dev/null
+++ b/libc/src/mathvec/generic/cospif.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD cospif vector 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/mathvec/cospif.h"
+#include "src/__support/mathvec/cospif.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, cospif, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(cospif)) {
+ return mathvec::cospif(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/sinpif.cpp b/libc/src/mathvec/generic/sinpif.cpp
new file mode 100644
index 0000000000000..94948a56fa4d1
--- /dev/null
+++ b/libc/src/mathvec/generic/sinpif.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD sinpif vector 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/mathvec/sinpif.h"
+#include "src/__support/mathvec/sinpif.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, sinpif, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(sinpif)) {
+ return mathvec::sinpif(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/tanpif.cpp b/libc/src/mathvec/generic/tanpif.cpp
new file mode 100644
index 0000000000000..22043074adb7a
--- /dev/null
+++ b/libc/src/mathvec/generic/tanpif.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD tanpif vector 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/mathvec/tanpif.h"
+#include "src/__support/mathvec/tanpif.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, tanpif, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(tanpif)) {
+ return mathvec::tanpif(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/sinpif.h b/libc/src/mathvec/sinpif.h
new file mode 100644
index 0000000000000..f6563ee2d7a1c
--- /dev/null
+++ b/libc/src/mathvec/sinpif.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD sinpif -------------------*- 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_MATHVEC_SINPIF_H
+#define LLVM_LIBC_SRC_MATHVEC_SINPIF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> sinpif(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_SINPIF_H
diff --git a/libc/src/mathvec/tanpif.h b/libc/src/mathvec/tanpif.h
new file mode 100644
index 0000000000000..8fd781303d39e
--- /dev/null
+++ b/libc/src/mathvec/tanpif.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD tanpif -------------------*- 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_MATHVEC_TANPIF_H
+#define LLVM_LIBC_SRC_MATHVEC_TANPIF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> tanpif(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_TANPIF_H
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index e3f54841d2891..3a40a5dfb20db 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -78,6 +78,25 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ cospif_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ cospif_test.cpp
+ HDRS
+ ../math/sdcomp26094.h
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.cospif
+ libc.src.mathvec.cospif
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
exp2f_test
SUITE
@@ -199,6 +218,25 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ sinpif_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ sinpif_test.cpp
+ HDRS
+ ../math/sdcomp26094.h
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.sinpif
+ libc.src.mathvec.sinpif
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
tanf_test
SUITE
@@ -218,6 +256,25 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ tanpif_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ tanpif_test.cpp
+ HDRS
+ ../math/sdcomp26094.h
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.tanpif
+ libc.src.mathvec.tanpif
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
if(NOT LLVM_LIBC_FULL_BUILD)
add_subdirectory(exhaustive)
endif()
diff --git a/libc/test/src/mathvec/cospif_test.cpp b/libc/test/src/mathvec/cospif_test.cpp
new file mode 100644
index 0000000000000..fe43de794466a
--- /dev/null
+++ b/libc/test/src/mathvec/cospif_test.cpp
@@ -0,0 +1,106 @@
+//===-- Unittests for cospif ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/cospif.h"
+#include "src/mathvec/cospif.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/math/sdcomp26094.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecCospifTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using CospifOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::cospif,
+ LIBC_NAMESPACE::cospif>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecCospifTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<CospifOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<CospifOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<CospifOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<CospifOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<CospifOp>(-0.0f));
+}
+
+TEST_F(LlvmLibcVecCospifTest, SpecificBitPatterns) {
+ constexpr int N = 38;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f00'0000U, // x = 0.5
+ 0x461d'd600U, // x = 10101.5
+ 0x3f06'0a92U, // x = pi/6
+ 0x3f3a'dc51U, // x = 0x1.75b8a2p-1f
+ 0x3f49'0fdbU, // x = pi/4
+ 0x3f86'0a92U, // x = pi/3
+ 0x3fa7'832aU, // x = 0x1.4f0654p+0f
+ 0x3fc9'0fdbU, // x = pi/2
+ 0x4017'1973U, // x = 0x1.2e32e6p+1f
+ 0x4049'0fdbU, // x = pi
+ 0x4096'cbe4U, // x = 0x1.2d97c8p+2f
+ 0x40c9'0fdbU, // x = 2*pi
+ 0x433b'7490U, // x = 0x1.76e92p+7f
+ 0x437c'e5f1U, // x = 0x1.f9cbe2p+7f
+ 0x4619'9998U, // x = 0x1.33333p+13f
+ 0x474d'246fU, // x = 0x1.9a48dep+15f
+ 0x4afd'ece4U, // x = 0x1.fbd9c8p+22f
+ 0x4c23'32e9U, // x = 0x1.4665d2p+25f
+ 0x50a3'e87fU, // x = 0x1.47d0fep+34f
+ 0x5239'47f6U, // x = 0x1.728fecp+37f
+ 0x53b1'46a6U, // x = 0x1.628d4cp+40f
+ 0x55ca'fb2aU, // x = 0x1.95f654p+44f
+ 0x588e'f060U, // x = 0x1.1de0cp+50f
+ 0x5c07'bcd0U, // x = 0x1.0f79ap+57f
+ 0x5ebc'fddeU, // x = 0x1.79fbbcp+62f
+ 0x5fa6'eba7U, // x = 0x1.4dd74ep+64f
+ 0x61a4'0b40U, // x = 0x1.48168p+68f
+ 0x6386'134eU, // x = 0x1.0c269cp+72f
+ 0x6589'8498U, // x = 0x1.13093p+76f
+ 0x6600'0001U, // x = 0x1.000002p+77f
+ 0x664e'46e4U, // x = 0x1.9c8dc8p+77f
+ 0x66b0'14aaU, // x = 0x1.602954p+78f
+ 0x67a9'242bU, // x = 0x1.524856p+80f
+ 0x6a19'76f1U, // x = 0x1.32ede2p+85f
+ 0x6c55'da58U, // x = 0x1.abb4bp+89f
+ 0x6f79'be45U, // x = 0x1.f37c8ap+95f
+ 0x7276'69d4U, // x = 0x1.ecd3a8p+101f
+ 0x7758'4625U, // x = 0x1.b08c4ap+111f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<CospifOp>(x, -x), wrap_vector<CospifOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecCospifTest, SDCOMP_26094) {
+ for (uint32_t v : SDCOMP26094_VALUES) {
+ float x = FPBits((v)).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<CospifOp>(x, -x), wrap_vector<CospifOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecCospifTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, CospifOp);
+ }
+}
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index 9bf3dfbd50fd4..ce9951a7d9bfe 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -73,6 +73,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ cospif_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ cospif_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.cospif
+ libc.src.mathvec.cospif
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
exp2f_test
NO_RUN_POSTBUILD
@@ -185,6 +201,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ sinpif_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ sinpif_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.sinpif
+ libc.src.mathvec.sinpif
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
tanf_test
NO_RUN_POSTBUILD
@@ -200,3 +232,19 @@ add_fp_unittest(
LINK_LIBRARIES
-lpthread
)
+
+add_fp_unittest(
+ tanpif_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ tanpif_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.tanpif
+ libc.src.mathvec.tanpif
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
diff --git a/libc/test/src/mathvec/exhaustive/cospif_test.cpp b/libc/test/src/mathvec/exhaustive/cospif_test.cpp
new file mode 100644
index 0000000000000..9d7b09d00ba84
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/cospif_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD cospif -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/cospif.h"
+#include "src/mathvec/cospif.h"
+
+using LlvmLibcCospifExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::cospif,
+ LIBC_NAMESPACE::cospif>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcCospifExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/sinpif_test.cpp b/libc/test/src/mathvec/exhaustive/sinpif_test.cpp
new file mode 100644
index 0000000000000..25c9cf3b6e1ca
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/sinpif_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD sinpif -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/sinpif.h"
+#include "src/mathvec/sinpif.h"
+
+using LlvmLibcSinpifExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::sinpif,
+ LIBC_NAMESPACE::sinpif>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcSinpifExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/tanpif_test.cpp b/libc/test/src/mathvec/exhaustive/tanpif_test.cpp
new file mode 100644
index 0000000000000..6444f97aad367
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/tanpif_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD tanpif -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/tanpif.h"
+#include "src/mathvec/tanpif.h"
+
+using LlvmLibcTanpifExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::tanpif,
+ LIBC_NAMESPACE::tanpif>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcTanpifExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/sinpif_test.cpp b/libc/test/src/mathvec/sinpif_test.cpp
new file mode 100644
index 0000000000000..77ee73afcc09e
--- /dev/null
+++ b/libc/test/src/mathvec/sinpif_test.cpp
@@ -0,0 +1,102 @@
+//===-- Unittests for sinpif ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/sinpif.h"
+#include "src/mathvec/sinpif.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/math/sdcomp26094.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecSinpifTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using SinpifOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::sinpif,
+ LIBC_NAMESPACE::sinpif>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecSinpifTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SinpifOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SinpifOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SinpifOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<SinpifOp>(0.0f));
+}
+
+TEST_F(LlvmLibcVecSinpifTest, SpecificBitPatterns) {
+ constexpr int N = 36;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f06'0a92U, // x = pi/6
+ 0x3f3a'dc51U, // x = 0x1.75b8a2p-1f
+ 0x3f49'0fdbU, // x = pi/4
+ 0x3f86'0a92U, // x = pi/3
+ 0x3fa7'832aU, // x = 0x1.4f0654p+0f
+ 0x3fc9'0fdbU, // x = pi/2
+ 0x4017'1973U, // x = 0x1.2e32e6p+1f
+ 0x4049'0fdbU, // x = pi
+ 0x4096'cbe4U, // x = 0x1.2d97c8p+2f
+ 0x40c9'0fdbU, // x = 2*pi
+ 0x433b'7490U, // x = 0x1.76e92p+7f
+ 0x437c'e5f1U, // x = 0x1.f9cbe2p+7f
+ 0x4619'9998U, // x = 0x1.33333p+13f
+ 0x474d'246fU, // x = 0x1.9a48dep+15f
+ 0x4afd'ece4U, // x = 0x1.fbd9c8p+22f
+ 0x4c23'32e9U, // x = 0x1.4665d2p+25f
+ 0x50a3'e87fU, // x = 0x1.47d0fep+34f
+ 0x5239'47f6U, // x = 0x1.728fecp+37f
+ 0x53b1'46a6U, // x = 0x1.628d4cp+40f
+ 0x55ca'fb2aU, // x = 0x1.95f654p+44f
+ 0x588e'f060U, // x = 0x1.1de0cp+50f
+ 0x5c07'bcd0U, // x = 0x1.0f79ap+57f
+ 0x5ebc'fddeU, // x = 0x1.79fbbcp+62f
+ 0x5fa6'eba7U, // x = 0x1.4dd74ep+64f
+ 0x61a4'0b40U, // x = 0x1.48168p+68f
+ 0x6386'134eU, // x = 0x1.0c269cp+72f
+ 0x6589'8498U, // x = 0x1.13093p+76f
+ 0x6600'0001U, // x = 0x1.000002p+77f
+ 0x664e'46e4U, // x = 0x1.9c8dc8p+77f
+ 0x66b0'14aaU, // x = 0x1.602954p+78f
+ 0x67a9'242bU, // x = 0x1.524856p+80f
+ 0x6a19'76f1U, // x = 0x1.32ede2p+85f
+ 0x6c55'da58U, // x = 0x1.abb4bp+89f
+ 0x6f79'be45U, // x = 0x1.f37c8ap+95f
+ 0x7276'69d4U, // x = 0x1.ecd3a8p+101f
+ 0x7758'4625U, // x = 0x1.b08c4ap+111f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<SinpifOp>(x, -x), wrap_vector<SinpifOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecSinpifTest, SDCOMP_26094) {
+ for (uint32_t v : SDCOMP26094_VALUES) {
+ float x = FPBits((v)).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<SinpifOp>(x, -x), wrap_vector<SinpifOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecSinpifTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, SinpifOp);
+ }
+}
diff --git a/libc/test/src/mathvec/tanpif_test.cpp b/libc/test/src/mathvec/tanpif_test.cpp
new file mode 100644
index 0000000000000..d73d6d1416648
--- /dev/null
+++ b/libc/test/src/mathvec/tanpif_test.cpp
@@ -0,0 +1,115 @@
+//===-- Unittests for tanpif ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/tanpif.h"
+#include "src/mathvec/tanpif.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/math/sdcomp26094.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecTanpifTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using TanpifOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::tanpif,
+ LIBC_NAMESPACE::tanpif>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::SDCOMP26094_VALUES;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecTanpifTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<TanpifOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<TanpifOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<TanpifOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<TanpifOp>(0.5f));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<TanpifOp>(-0.5f));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<TanpifOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(-0.0f), wrap_vector<TanpifOp>(-0.0f));
+}
+
+TEST_F(LlvmLibcVecTanpifTest, SpecificBitPatterns) {
+ constexpr int N = 38;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f00'0000U, // x = 0.5
+ 0x461d'd600U, // x = 10101.5
+ 0x3f06'0a92U, // x = pi/6
+ 0x3f3a'dc51U, // x = 0x1.75b8a2p-1f
+ 0x3f49'0fdbU, // x = pi/4
+ 0x3f86'0a92U, // x = pi/3
+ 0x3fa7'832aU, // x = 0x1.4f0654p+0f
+ 0x3fc9'0fdbU, // x = pi/2
+ 0x4017'1973U, // x = 0x1.2e32e6p+1f
+ 0x4049'0fdbU, // x = pi
+ 0x4096'cbe4U, // x = 0x1.2d97c8p+2f
+ 0x40c9'0fdbU, // x = 2*pi
+ 0x433b'7490U, // x = 0x1.76e92p+7f
+ 0x437c'e5f1U, // x = 0x1.f9cbe2p+7f
+ 0x4619'9998U, // x = 0x1.33333p+13f
+ 0x474d'246fU, // x = 0x1.9a48dep+15f
+ 0x4afd'ece4U, // x = 0x1.fbd9c8p+22f
+ 0x4c23'32e9U, // x = 0x1.4665d2p+25f
+ 0x50a3'e87fU, // x = 0x1.47d0fep+34f
+ 0x5239'47f6U, // x = 0x1.728fecp+37f
+ 0x53b1'46a6U, // x = 0x1.628d4cp+40f
+ 0x55ca'fb2aU, // x = 0x1.95f654p+44f
+ 0x588e'f060U, // x = 0x1.1de0cp+50f
+ 0x5c07'bcd0U, // x = 0x1.0f79ap+57f
+ 0x5ebc'fddeU, // x = 0x1.79fbbcp+62f
+ 0x5fa6'eba7U, // x = 0x1.4dd74ep+64f
+ 0x61a4'0b40U, // x = 0x1.48168p+68f
+ 0x6386'134eU, // x = 0x1.0c269cp+72f
+ 0x6589'8498U, // x = 0x1.13093p+76f
+ 0x6600'0001U, // x = 0x1.000002p+77f
+ 0x664e'46e4U, // x = 0x1.9c8dc8p+77f
+ 0x66b0'14aaU, // x = 0x1.602954p+78f
+ 0x67a9'242bU, // x = 0x1.524856p+80f
+ 0x6a19'76f1U, // x = 0x1.32ede2p+85f
+ 0x6c55'da58U, // x = 0x1.abb4bp+89f
+ 0x6f79'be45U, // x = 0x1.f37c8ap+95f
+ 0x7276'69d4U, // x = 0x1.ecd3a8p+101f
+ 0x7758'4625U, // x = 0x1.b08c4ap+111f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<TanpifOp>(x, -x), wrap_vector<TanpifOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecTanpifTest, SDCOMP_26094) {
+ for (uint32_t v : SDCOMP26094_VALUES) {
+ float x = FPBits((v)).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<TanpifOp>(x, -x), wrap_vector<TanpifOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecTanpifTest, Poles) {
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<TanpifOp>(0.5f));
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<TanpifOp>(-0.5f));
+}
+
+TEST_F(LlvmLibcVecTanpifTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, TanpifOp);
+ }
+}
>From 7652d0319f278c33737f87870450a38dc6a972fa Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 19:15:10 +0000
Subject: [PATCH 08/12] Add acospif/asinpif as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 2 +
libc/config/linux/x86_64/entrypoints.txt | 2 +
libc/src/__support/mathvec/CMakeLists.txt | 18 ++++++
libc/src/__support/mathvec/acospif.h | 34 +++++++++++
libc/src/__support/mathvec/asinpif.h | 34 +++++++++++
libc/src/mathvec/CMakeLists.txt | 2 +
libc/src/mathvec/acospif.h | 21 +++++++
libc/src/mathvec/asinpif.h | 21 +++++++
libc/src/mathvec/generic/CMakeLists.txt | 28 ++++++++++
libc/src/mathvec/generic/acospif.cpp | 20 +++++++
libc/src/mathvec/generic/asinpif.cpp | 20 +++++++
libc/test/src/mathvec/CMakeLists.txt | 34 +++++++++++
libc/test/src/mathvec/acospif_test.cpp | 56 +++++++++++++++++++
libc/test/src/mathvec/asinpif_test.cpp | 56 +++++++++++++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 32 +++++++++++
.../src/mathvec/exhaustive/acospif_test.cpp | 19 +++++++
.../src/mathvec/exhaustive/asinpif_test.cpp | 19 +++++++
17 files changed, 418 insertions(+)
create mode 100644 libc/src/__support/mathvec/acospif.h
create mode 100644 libc/src/__support/mathvec/asinpif.h
create mode 100644 libc/src/mathvec/acospif.h
create mode 100644 libc/src/mathvec/asinpif.h
create mode 100644 libc/src/mathvec/generic/acospif.cpp
create mode 100644 libc/src/mathvec/generic/asinpif.cpp
create mode 100644 libc/test/src/mathvec/acospif_test.cpp
create mode 100644 libc/test/src/mathvec/asinpif_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/acospif_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/asinpif_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 29911fbdc311b..a3a36794a4464 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1286,7 +1286,9 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.acosf
+ libc.src.mathvec.acospif
libc.src.mathvec.asinf
+ libc.src.mathvec.asinpif
libc.src.mathvec.atanf
libc.src.mathvec.cosf
libc.src.mathvec.cospif
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 0468152f2d3cf..22ad0296f185f 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1509,7 +1509,9 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.acosf
+ libc.src.mathvec.acospif
libc.src.mathvec.asinf
+ libc.src.mathvec.asinpif
libc.src.mathvec.atanf
libc.src.mathvec.cosf
libc.src.mathvec.cospif
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index e08e6fa6ebba5..8109e6f8b897c 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -9,6 +9,15 @@ add_header_library(
libc.src.__support.math.acosf
)
+add_header_library(
+ acospif
+ HDRS
+ acospif.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.acospif
+)
+
add_header_library(
asinf
HDRS
@@ -18,6 +27,15 @@ add_header_library(
libc.src.__support.math.asinf
)
+add_header_library(
+ asinpif
+ HDRS
+ asinpif.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.asinpif
+)
+
add_header_library(
atanf
HDRS
diff --git a/libc/src/__support/mathvec/acospif.h b/libc/src/__support/mathvec/acospif.h
new file mode 100644
index 0000000000000..fabf14162dacf
--- /dev/null
+++ b/libc/src/__support/mathvec/acospif.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD acospif -----------------*- 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_MATHVEC_ACOSPIF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_ACOSPIF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/acospif.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> acospif(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::acospif(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_ACOSPIF_H
diff --git a/libc/src/__support/mathvec/asinpif.h b/libc/src/__support/mathvec/asinpif.h
new file mode 100644
index 0000000000000..8b1c12801a606
--- /dev/null
+++ b/libc/src/__support/mathvec/asinpif.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD asinpif -----------------*- 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_MATHVEC_ASINPIF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_ASINPIF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/asinpif.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> asinpif(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::asinpif(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_ASINPIF_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index 8a2108cf2ee3f..a55cf91b9e71a 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -50,7 +50,9 @@ function(add_vector_math_entrypoint_object name)
endfunction()
add_vector_math_entrypoint_object(acosf)
+add_vector_math_entrypoint_object(acospif)
add_vector_math_entrypoint_object(asinf)
+add_vector_math_entrypoint_object(asinpif)
add_vector_math_entrypoint_object(atanf)
add_vector_math_entrypoint_object(cosf)
add_vector_math_entrypoint_object(cospif)
diff --git a/libc/src/mathvec/acospif.h b/libc/src/mathvec/acospif.h
new file mode 100644
index 0000000000000..46826c5197e8d
--- /dev/null
+++ b/libc/src/mathvec/acospif.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD acospif ------------------*- 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_MATHVEC_ACOSPIF_H
+#define LLVM_LIBC_SRC_MATHVEC_ACOSPIF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> acospif(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_ACOSPIF_H
diff --git a/libc/src/mathvec/asinpif.h b/libc/src/mathvec/asinpif.h
new file mode 100644
index 0000000000000..5a2214e3d18ae
--- /dev/null
+++ b/libc/src/mathvec/asinpif.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD asinpif ------------------*- 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_MATHVEC_ASINPIF_H
+#define LLVM_LIBC_SRC_MATHVEC_ASINPIF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> asinpif(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_ASINPIF_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index 6460e0e28c03a..df3badd14cefe 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -12,6 +12,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ acospif
+ SRCS
+ acospif.cpp
+ HDRS
+ ../acospif.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.acospif
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
asinf
SRCS
@@ -26,6 +40,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ asinpif
+ SRCS
+ asinpif.cpp
+ HDRS
+ ../asinpif.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.asinpif
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
atanf
SRCS
diff --git a/libc/src/mathvec/generic/acospif.cpp b/libc/src/mathvec/generic/acospif.cpp
new file mode 100644
index 0000000000000..e27a699d1ae04
--- /dev/null
+++ b/libc/src/mathvec/generic/acospif.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD acospif vector 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/mathvec/acospif.h"
+#include "src/__support/mathvec/acospif.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, acospif, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(acospif)) {
+ return mathvec::acospif(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/asinpif.cpp b/libc/src/mathvec/generic/asinpif.cpp
new file mode 100644
index 0000000000000..dc6864a9767ae
--- /dev/null
+++ b/libc/src/mathvec/generic/asinpif.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD asinpif vector 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/mathvec/asinpif.h"
+#include "src/__support/mathvec/asinpif.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, asinpif, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(asinpif)) {
+ return mathvec::asinpif(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index 3a40a5dfb20db..bdc4390b2b798 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -25,6 +25,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ acospif_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ acospif_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.acospif
+ libc.src.mathvec.acospif
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
asinf_test
SUITE
@@ -42,6 +59,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ asinpif_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ asinpif_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.asinpif
+ libc.src.mathvec.asinpif
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
atanf_test
SUITE
diff --git a/libc/test/src/mathvec/acospif_test.cpp b/libc/test/src/mathvec/acospif_test.cpp
new file mode 100644
index 0000000000000..611a5db0bea59
--- /dev/null
+++ b/libc/test/src/mathvec/acospif_test.cpp
@@ -0,0 +1,56 @@
+//===-- Unittests for acospif ---------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/acospif.h"
+#include "src/mathvec/acospif.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecAcospifTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using AcospifOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::acospif,
+ LIBC_NAMESPACE::acospif>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecAcospifTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcospifOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcospifOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcospifOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcospifOp>(2.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcospifOp>(-2.0f));
+
+ EXPECT_SIMD_EQ(splat(0.5f), wrap_vector<AcospifOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(0.5f), wrap_vector<AcospifOp>(-0.0f));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<AcospifOp>(1.0f));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<AcospifOp>(-1.0f));
+}
+
+TEST_F(LlvmLibcVecAcospifTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, AcospifOp);
+ }
+}
diff --git a/libc/test/src/mathvec/asinpif_test.cpp b/libc/test/src/mathvec/asinpif_test.cpp
new file mode 100644
index 0000000000000..d9bba97fdeed3
--- /dev/null
+++ b/libc/test/src/mathvec/asinpif_test.cpp
@@ -0,0 +1,56 @@
+//===-- Unittests for asinpif ---------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/asinpif.h"
+#include "src/mathvec/asinpif.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecAsinpifTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using AsinpifOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::asinpif,
+ LIBC_NAMESPACE::asinpif>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecAsinpifTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinpifOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinpifOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinpifOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinpifOp>(2.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinpifOp>(-2.0f));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<AsinpifOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(-0.0f), wrap_vector<AsinpifOp>(-0.0f));
+
+ EXPECT_SIMD_EQ(splat(0.5f), wrap_vector<AsinpifOp>(1.0f));
+
+ EXPECT_SIMD_EQ(splat(-0.5f), wrap_vector<AsinpifOp>(-1.0f));
+}
+
+TEST_F(LlvmLibcVecAsinpifTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, AsinpifOp);
+ }
+}
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index ce9951a7d9bfe..816aeafab06af 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -25,6 +25,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ acospif_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ acospif_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.acospif
+ libc.src.mathvec.acospif
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
asinf_test
NO_RUN_POSTBUILD
@@ -41,6 +57,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ asinpif_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ asinpif_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.asinpif
+ libc.src.mathvec.asinpif
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
atanf_test
NO_RUN_POSTBUILD
diff --git a/libc/test/src/mathvec/exhaustive/acospif_test.cpp b/libc/test/src/mathvec/exhaustive/acospif_test.cpp
new file mode 100644
index 0000000000000..0cf8f2a4163be
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/acospif_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD acospif ----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/acospif.h"
+#include "src/mathvec/acospif.h"
+
+using LlvmLibcAcospifExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::acospif,
+ LIBC_NAMESPACE::acospif>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcAcospifExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/asinpif_test.cpp b/libc/test/src/mathvec/exhaustive/asinpif_test.cpp
new file mode 100644
index 0000000000000..af145f691d911
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/asinpif_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD asinpif ----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/asinpif.h"
+#include "src/mathvec/asinpif.h"
+
+using LlvmLibcAsinpifExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::asinpif,
+ LIBC_NAMESPACE::asinpif>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcAsinpifExhaustiveTest, EntireRange) { test_full_range_RN(); }
>From 0de176efe3137d96c4bbec6e410cfd9f027995aa Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 19:22:54 +0000
Subject: [PATCH 09/12] Add coshf/sinhf/tanhf as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 3 +
libc/config/linux/x86_64/entrypoints.txt | 3 +
libc/src/__support/mathvec/CMakeLists.txt | 27 ++++++++
libc/src/__support/mathvec/coshf.h | 34 ++++++++++
libc/src/__support/mathvec/sinhf.h | 34 ++++++++++
libc/src/__support/mathvec/tanhf.h | 34 ++++++++++
libc/src/mathvec/CMakeLists.txt | 3 +
libc/src/mathvec/coshf.h | 20 ++++++
libc/src/mathvec/generic/CMakeLists.txt | 42 +++++++++++++
libc/src/mathvec/generic/coshf.cpp | 20 ++++++
libc/src/mathvec/generic/sinhf.cpp | 20 ++++++
libc/src/mathvec/generic/tanhf.cpp | 20 ++++++
libc/src/mathvec/sinhf.h | 20 ++++++
libc/src/mathvec/tanhf.h | 20 ++++++
libc/test/src/mathvec/CMakeLists.txt | 51 +++++++++++++++
libc/test/src/mathvec/coshf_test.cpp | 57 +++++++++++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 48 ++++++++++++++
.../src/mathvec/exhaustive/coshf_test.cpp | 19 ++++++
.../src/mathvec/exhaustive/sinhf_test.cpp | 19 ++++++
.../src/mathvec/exhaustive/tanhf_test.cpp | 19 ++++++
libc/test/src/mathvec/sinhf_test.cpp | 62 +++++++++++++++++++
libc/test/src/mathvec/tanhf_test.cpp | 61 ++++++++++++++++++
22 files changed, 636 insertions(+)
create mode 100644 libc/src/__support/mathvec/coshf.h
create mode 100644 libc/src/__support/mathvec/sinhf.h
create mode 100644 libc/src/__support/mathvec/tanhf.h
create mode 100644 libc/src/mathvec/coshf.h
create mode 100644 libc/src/mathvec/generic/coshf.cpp
create mode 100644 libc/src/mathvec/generic/sinhf.cpp
create mode 100644 libc/src/mathvec/generic/tanhf.cpp
create mode 100644 libc/src/mathvec/sinhf.h
create mode 100644 libc/src/mathvec/tanhf.h
create mode 100644 libc/test/src/mathvec/coshf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/coshf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/sinhf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/tanhf_test.cpp
create mode 100644 libc/test/src/mathvec/sinhf_test.cpp
create mode 100644 libc/test/src/mathvec/tanhf_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index a3a36794a4464..ed113eda6dbf2 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1291,6 +1291,7 @@ if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
libc.src.mathvec.asinpif
libc.src.mathvec.atanf
libc.src.mathvec.cosf
+ libc.src.mathvec.coshf
libc.src.mathvec.cospif
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
@@ -1299,8 +1300,10 @@ if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
libc.src.mathvec.expf
libc.src.mathvec.expm1f
libc.src.mathvec.sinf
+ libc.src.mathvec.sinhf
libc.src.mathvec.sinpif
libc.src.mathvec.tanf
+ libc.src.mathvec.tanhf
libc.src.mathvec.tanpif
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 22ad0296f185f..3c56ba43a6f2a 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1514,6 +1514,7 @@ list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.asinpif
libc.src.mathvec.atanf
libc.src.mathvec.cosf
+ libc.src.mathvec.coshf
libc.src.mathvec.cospif
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
@@ -1522,8 +1523,10 @@ list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.expf
libc.src.mathvec.expm1f
libc.src.mathvec.sinf
+ libc.src.mathvec.sinhf
libc.src.mathvec.sinpif
libc.src.mathvec.tanf
+ libc.src.mathvec.tanhf
libc.src.mathvec.tanpif
)
endif()
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index 8109e6f8b897c..89023b94d540b 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -54,6 +54,15 @@ add_header_library(
libc.src.__support.math.cosf
)
+add_header_library(
+ coshf
+ HDRS
+ coshf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.coshf
+)
+
add_header_library(
cospif
HDRS
@@ -138,6 +147,15 @@ add_header_library(
libc.src.__support.math.sinf
)
+add_header_library(
+ sinhf
+ HDRS
+ sinhf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.sinhf
+)
+
add_header_library(
sinpif
HDRS
@@ -156,6 +174,15 @@ add_header_library(
libc.src.__support.math.tanf
)
+add_header_library(
+ tanhf
+ HDRS
+ tanhf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.tanhf
+)
+
add_header_library(
tanpif
HDRS
diff --git a/libc/src/__support/mathvec/coshf.h b/libc/src/__support/mathvec/coshf.h
new file mode 100644
index 0000000000000..8d788e8ffa369
--- /dev/null
+++ b/libc/src/__support/mathvec/coshf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD coshf ------------------*- 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_MATHVEC_COSHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_COSHF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/coshf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> coshf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::coshf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_COSHF_H
diff --git a/libc/src/__support/mathvec/sinhf.h b/libc/src/__support/mathvec/sinhf.h
new file mode 100644
index 0000000000000..51233b936df2c
--- /dev/null
+++ b/libc/src/__support/mathvec/sinhf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD sinhf ------------------*- 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_MATHVEC_SINHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINHF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/sinhf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> sinhf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::sinhf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_SINHF_H
diff --git a/libc/src/__support/mathvec/tanhf.h b/libc/src/__support/mathvec/tanhf.h
new file mode 100644
index 0000000000000..84b47832f676d
--- /dev/null
+++ b/libc/src/__support/mathvec/tanhf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD tanhf ------------------*- 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_MATHVEC_TANHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_TANHF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/tanhf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> tanhf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::tanhf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_TANHF_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index a55cf91b9e71a..46638c6cf07af 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -55,6 +55,7 @@ add_vector_math_entrypoint_object(asinf)
add_vector_math_entrypoint_object(asinpif)
add_vector_math_entrypoint_object(atanf)
add_vector_math_entrypoint_object(cosf)
+add_vector_math_entrypoint_object(coshf)
add_vector_math_entrypoint_object(cospif)
add_vector_math_entrypoint_object(exp2f)
add_vector_math_entrypoint_object(exp2m1f)
@@ -63,6 +64,8 @@ add_vector_math_entrypoint_object(exp10m1f)
add_vector_math_entrypoint_object(expf)
add_vector_math_entrypoint_object(expm1f)
add_vector_math_entrypoint_object(sinf)
+add_vector_math_entrypoint_object(sinhf)
add_vector_math_entrypoint_object(sinpif)
add_vector_math_entrypoint_object(tanf)
+add_vector_math_entrypoint_object(tanhf)
add_vector_math_entrypoint_object(tanpif)
diff --git a/libc/src/mathvec/coshf.h b/libc/src/mathvec/coshf.h
new file mode 100644
index 0000000000000..802e1388d2c68
--- /dev/null
+++ b/libc/src/mathvec/coshf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD coshf --------------------*- 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_MATHVEC_COSHF_H
+#define LLVM_LIBC_SRC_MATHVEC_COSHF_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> coshf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_COSHF_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index df3badd14cefe..3bc441a7a5c83 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -82,6 +82,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ coshf
+ SRCS
+ coshf.cpp
+ HDRS
+ ../coshf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.coshf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
cospif
SRCS
@@ -194,6 +208,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ sinhf
+ SRCS
+ sinhf.cpp
+ HDRS
+ ../sinhf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.sinhf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
sinpif
SRCS
@@ -222,6 +250,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ tanhf
+ SRCS
+ tanhf.cpp
+ HDRS
+ ../tanhf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.tanhf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
tanpif
SRCS
diff --git a/libc/src/mathvec/generic/coshf.cpp b/libc/src/mathvec/generic/coshf.cpp
new file mode 100644
index 0000000000000..11beede36d802
--- /dev/null
+++ b/libc/src/mathvec/generic/coshf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD coshf vector 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/mathvec/coshf.h"
+#include "src/__support/mathvec/coshf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, coshf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(coshf)) {
+ return mathvec::coshf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/sinhf.cpp b/libc/src/mathvec/generic/sinhf.cpp
new file mode 100644
index 0000000000000..4ef1fbd562a29
--- /dev/null
+++ b/libc/src/mathvec/generic/sinhf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD sinhf vector 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/mathvec/sinhf.h"
+#include "src/__support/mathvec/sinhf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, sinhf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(sinhf)) {
+ return mathvec::sinhf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/tanhf.cpp b/libc/src/mathvec/generic/tanhf.cpp
new file mode 100644
index 0000000000000..7fa089c0028b5
--- /dev/null
+++ b/libc/src/mathvec/generic/tanhf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD tanhf vector 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/mathvec/tanhf.h"
+#include "src/__support/mathvec/tanhf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, tanhf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(tanhf)) {
+ return mathvec::tanhf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/sinhf.h b/libc/src/mathvec/sinhf.h
new file mode 100644
index 0000000000000..6a1b878fd87d0
--- /dev/null
+++ b/libc/src/mathvec/sinhf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD sinhf --------------------*- 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_MATHVEC_SINHF_H
+#define LLVM_LIBC_SRC_MATHVEC_SINHF_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> sinhf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_SINHF_H
diff --git a/libc/src/mathvec/tanhf.h b/libc/src/mathvec/tanhf.h
new file mode 100644
index 0000000000000..6ecfeb02e0830
--- /dev/null
+++ b/libc/src/mathvec/tanhf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD tanhf --------------------*- 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_MATHVEC_TANHF_H
+#define LLVM_LIBC_SRC_MATHVEC_TANHF_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> tanhf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_TANHF_H
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index bdc4390b2b798..5d5a42d551f46 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -112,6 +112,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ coshf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ coshf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.coshf
+ libc.src.mathvec.coshf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
cospif_test
SUITE
@@ -252,6 +269,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ sinhf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ sinhf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.sinhf
+ libc.src.mathvec.sinhf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
sinpif_test
SUITE
@@ -290,6 +324,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ tanhf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ tanhf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.tanhf
+ libc.src.mathvec.tanhf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
tanpif_test
SUITE
diff --git a/libc/test/src/mathvec/coshf_test.cpp b/libc/test/src/mathvec/coshf_test.cpp
new file mode 100644
index 0000000000000..0b67cff4108d7
--- /dev/null
+++ b/libc/test/src/mathvec/coshf_test.cpp
@@ -0,0 +1,57 @@
+//===-- Unittests for coshf ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/coshf.h"
+#include "src/mathvec/coshf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecCoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using CoshfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::coshf,
+ LIBC_NAMESPACE::coshf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecCoshfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<CoshfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<CoshfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<CoshfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<CoshfOp>(0.0f));
+}
+
+TEST_F(LlvmLibcVecCoshfTest, Overflow) {
+ float x = FPBits(0x7f7fffffU).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<CoshfOp>(x, -x), wrap_vector<CoshfOp>(x, -x));
+
+ x = FPBits(0x42cffff8U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<CoshfOp>(x, -x), wrap_vector<CoshfOp>(x, -x));
+
+ x = FPBits(0x42d00008U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<CoshfOp>(x, -x), wrap_vector<CoshfOp>(x, -x));
+}
+
+TEST_F(LlvmLibcVecCoshfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, CoshfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index 816aeafab06af..98dd2b90e9ad7 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -105,6 +105,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ coshf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ coshf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.coshf
+ libc.src.mathvec.coshf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
cospif_test
NO_RUN_POSTBUILD
@@ -233,6 +249,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ sinhf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ sinhf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.sinhf
+ libc.src.mathvec.sinhf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
sinpif_test
NO_RUN_POSTBUILD
@@ -265,6 +297,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ tanhf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ tanhf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.tanhf
+ libc.src.mathvec.tanhf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
tanpif_test
NO_RUN_POSTBUILD
diff --git a/libc/test/src/mathvec/exhaustive/coshf_test.cpp b/libc/test/src/mathvec/exhaustive/coshf_test.cpp
new file mode 100644
index 0000000000000..ab65c835796ad
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/coshf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD coshf ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/coshf.h"
+#include "src/mathvec/coshf.h"
+
+using LlvmLibcCoshfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::coshf,
+ LIBC_NAMESPACE::coshf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcCoshfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/sinhf_test.cpp b/libc/test/src/mathvec/exhaustive/sinhf_test.cpp
new file mode 100644
index 0000000000000..af6e736a0e5d6
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/sinhf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD sinhf ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/sinhf.h"
+#include "src/mathvec/sinhf.h"
+
+using LlvmLibcSinhfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::sinhf,
+ LIBC_NAMESPACE::sinhf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcSinhfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/tanhf_test.cpp b/libc/test/src/mathvec/exhaustive/tanhf_test.cpp
new file mode 100644
index 0000000000000..8818b8e9ab6f0
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/tanhf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD tanhf ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/tanhf.h"
+#include "src/mathvec/tanhf.h"
+
+using LlvmLibcTanhfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::tanhf,
+ LIBC_NAMESPACE::tanhf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcTanhfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/sinhf_test.cpp b/libc/test/src/mathvec/sinhf_test.cpp
new file mode 100644
index 0000000000000..76e78075a04f9
--- /dev/null
+++ b/libc/test/src/mathvec/sinhf_test.cpp
@@ -0,0 +1,62 @@
+//===-- Unittests for sinhf ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/sinhf.h"
+#include "src/mathvec/sinhf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecSinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using SinhfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::sinhf,
+ LIBC_NAMESPACE::sinhf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecSinhfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SinhfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<SinhfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<SinhfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<SinhfOp>(0.0f));
+}
+
+TEST_F(LlvmLibcVecSinhfTest, Overflow) {
+ float x = FPBits(0x7f7fffffU).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<SinhfOp>(x, -x), wrap_vector<SinhfOp>(x, -x));
+
+ x = FPBits(0x42cffff8U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<SinhfOp>(x, -x), wrap_vector<SinhfOp>(x, -x));
+
+ x = FPBits(0x42d00008U).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<SinhfOp>(x, -x), wrap_vector<SinhfOp>(x, -x));
+}
+
+TEST_F(LlvmLibcVecSinhfTest, ExceptionalValues) {
+ float x = FPBits(0x3a12'85ffU).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<SinhfOp>(x, -x), wrap_vector<SinhfOp>(x, -x));
+}
+
+TEST_F(LlvmLibcVecSinhfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, SinhfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/tanhf_test.cpp b/libc/test/src/mathvec/tanhf_test.cpp
new file mode 100644
index 0000000000000..5e4e7aa3a46cf
--- /dev/null
+++ b/libc/test/src/mathvec/tanhf_test.cpp
@@ -0,0 +1,61 @@
+//===-- Unittests for tanhf ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/tanhf.h"
+#include "src/mathvec/tanhf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecTanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using TanhfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::tanhf,
+ LIBC_NAMESPACE::tanhf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecTanhfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<TanhfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<TanhfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(-1.0f), wrap_vector<TanhfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<TanhfOp>(0.0f));
+}
+
+TEST_F(LlvmLibcVecTanhfTest, ExceptionalValues) {
+ constexpr int N = 4;
+ constexpr uint32_t INPUTS[N] = {
+ 0x0040'0000,
+ 0x1780'0000,
+ 0x3a12'85ff,
+ 0x4058'e0a3,
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<TanhfOp>(x, -x), wrap_vector<TanhfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecTanhfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, TanhfOp);
+ }
+}
>From e20c2859feb95fa4e537a805cc5ddeaddf397a3a Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 19:30:54 +0000
Subject: [PATCH 10/12] Add acoshf/asinhf/atanhf as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 3 +
libc/config/linux/x86_64/entrypoints.txt | 3 +
libc/src/__support/mathvec/CMakeLists.txt | 27 +++++++
libc/src/__support/mathvec/acoshf.h | 34 +++++++++
libc/src/__support/mathvec/asinhf.h | 34 +++++++++
libc/src/__support/mathvec/atanhf.h | 34 +++++++++
libc/src/mathvec/CMakeLists.txt | 3 +
libc/src/mathvec/acoshf.h | 20 +++++
libc/src/mathvec/asinhf.h | 20 +++++
libc/src/mathvec/atanhf.h | 20 +++++
libc/src/mathvec/generic/CMakeLists.txt | 42 ++++++++++
libc/src/mathvec/generic/acoshf.cpp | 20 +++++
libc/src/mathvec/generic/asinhf.cpp | 20 +++++
libc/src/mathvec/generic/atanhf.cpp | 20 +++++
libc/test/src/mathvec/CMakeLists.txt | 51 +++++++++++++
libc/test/src/mathvec/acoshf_test.cpp | 76 +++++++++++++++++++
libc/test/src/mathvec/asinhf_test.cpp | 74 ++++++++++++++++++
libc/test/src/mathvec/atanhf_test.cpp | 53 +++++++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 48 ++++++++++++
.../src/mathvec/exhaustive/acoshf_test.cpp | 19 +++++
.../src/mathvec/exhaustive/asinhf_test.cpp | 19 +++++
.../src/mathvec/exhaustive/atanhf_test.cpp | 19 +++++
22 files changed, 659 insertions(+)
create mode 100644 libc/src/__support/mathvec/acoshf.h
create mode 100644 libc/src/__support/mathvec/asinhf.h
create mode 100644 libc/src/__support/mathvec/atanhf.h
create mode 100644 libc/src/mathvec/acoshf.h
create mode 100644 libc/src/mathvec/asinhf.h
create mode 100644 libc/src/mathvec/atanhf.h
create mode 100644 libc/src/mathvec/generic/acoshf.cpp
create mode 100644 libc/src/mathvec/generic/asinhf.cpp
create mode 100644 libc/src/mathvec/generic/atanhf.cpp
create mode 100644 libc/test/src/mathvec/acoshf_test.cpp
create mode 100644 libc/test/src/mathvec/asinhf_test.cpp
create mode 100644 libc/test/src/mathvec/atanhf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/acoshf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/asinhf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/atanhf_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index ed113eda6dbf2..31bb10c497881 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1286,10 +1286,13 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.acosf
+ libc.src.mathvec.acoshf
libc.src.mathvec.acospif
libc.src.mathvec.asinf
+ libc.src.mathvec.asinhf
libc.src.mathvec.asinpif
libc.src.mathvec.atanf
+ libc.src.mathvec.atanhf
libc.src.mathvec.cosf
libc.src.mathvec.coshf
libc.src.mathvec.cospif
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 3c56ba43a6f2a..b5f45cdc6bc3e 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1509,10 +1509,13 @@ set(TARGET_LIBMVEC_ENTRYPOINTS)
if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.acosf
+ libc.src.mathvec.acoshf
libc.src.mathvec.acospif
libc.src.mathvec.asinf
+ libc.src.mathvec.asinhf
libc.src.mathvec.asinpif
libc.src.mathvec.atanf
+ libc.src.mathvec.atanhf
libc.src.mathvec.cosf
libc.src.mathvec.coshf
libc.src.mathvec.cospif
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index 89023b94d540b..df817eaa1d9b0 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -9,6 +9,15 @@ add_header_library(
libc.src.__support.math.acosf
)
+add_header_library(
+ acoshf
+ HDRS
+ acoshf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.acoshf
+)
+
add_header_library(
acospif
HDRS
@@ -27,6 +36,15 @@ add_header_library(
libc.src.__support.math.asinf
)
+add_header_library(
+ asinhf
+ HDRS
+ asinhf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.asinhf
+)
+
add_header_library(
asinpif
HDRS
@@ -45,6 +63,15 @@ add_header_library(
libc.src.__support.math.atanf
)
+add_header_library(
+ atanhf
+ HDRS
+ atanhf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.atanhf
+)
+
add_header_library(
cosf
HDRS
diff --git a/libc/src/__support/mathvec/acoshf.h b/libc/src/__support/mathvec/acoshf.h
new file mode 100644
index 0000000000000..48ccb219f48f5
--- /dev/null
+++ b/libc/src/__support/mathvec/acoshf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD acoshf -----------------*- 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_MATHVEC_ACOSHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_ACOSHF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/acoshf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> acoshf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::acoshf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_ACOSHF_H
diff --git a/libc/src/__support/mathvec/asinhf.h b/libc/src/__support/mathvec/asinhf.h
new file mode 100644
index 0000000000000..a9428ae8facf1
--- /dev/null
+++ b/libc/src/__support/mathvec/asinhf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD asinhf -----------------*- 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_MATHVEC_ASINHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_ASINHF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/asinhf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> asinhf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::asinhf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_ASINHF_H
diff --git a/libc/src/__support/mathvec/atanhf.h b/libc/src/__support/mathvec/atanhf.h
new file mode 100644
index 0000000000000..a861f724ffb5e
--- /dev/null
+++ b/libc/src/__support/mathvec/atanhf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD atanhf -----------------*- 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_MATHVEC_ATANHF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_ATANHF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/atanhf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> atanhf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::atanhf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_ATANHF_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index 46638c6cf07af..9a6bc238d4a1f 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -50,10 +50,13 @@ function(add_vector_math_entrypoint_object name)
endfunction()
add_vector_math_entrypoint_object(acosf)
+add_vector_math_entrypoint_object(acoshf)
add_vector_math_entrypoint_object(acospif)
add_vector_math_entrypoint_object(asinf)
+add_vector_math_entrypoint_object(asinhf)
add_vector_math_entrypoint_object(asinpif)
add_vector_math_entrypoint_object(atanf)
+add_vector_math_entrypoint_object(atanhf)
add_vector_math_entrypoint_object(cosf)
add_vector_math_entrypoint_object(coshf)
add_vector_math_entrypoint_object(cospif)
diff --git a/libc/src/mathvec/acoshf.h b/libc/src/mathvec/acoshf.h
new file mode 100644
index 0000000000000..8f6918004c1c7
--- /dev/null
+++ b/libc/src/mathvec/acoshf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD acoshf -------------------*- 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_MATHVEC_ACOSHF_H
+#define LLVM_LIBC_SRC_MATHVEC_ACOSHF_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> acoshf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_ACOSHF_H
diff --git a/libc/src/mathvec/asinhf.h b/libc/src/mathvec/asinhf.h
new file mode 100644
index 0000000000000..7b406e303f45a
--- /dev/null
+++ b/libc/src/mathvec/asinhf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD asinhf -------------------*- 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_MATHVEC_ASINHF_H
+#define LLVM_LIBC_SRC_MATHVEC_ASINHF_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> asinhf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_ASINHF_H
diff --git a/libc/src/mathvec/atanhf.h b/libc/src/mathvec/atanhf.h
new file mode 100644
index 0000000000000..050a62938784c
--- /dev/null
+++ b/libc/src/mathvec/atanhf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD atanhf -------------------*- 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_MATHVEC_ATANHF_H
+#define LLVM_LIBC_SRC_MATHVEC_ATANHF_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> atanhf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_ATANHF_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index 3bc441a7a5c83..28c26e1d2cda1 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -12,6 +12,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ acoshf
+ SRCS
+ acoshf.cpp
+ HDRS
+ ../acoshf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.acoshf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
acospif
SRCS
@@ -40,6 +54,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ asinhf
+ SRCS
+ asinhf.cpp
+ HDRS
+ ../asinhf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.asinhf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
asinpif
SRCS
@@ -68,6 +96,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ atanhf
+ SRCS
+ atanhf.cpp
+ HDRS
+ ../atanhf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.atanhf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
cosf
SRCS
diff --git a/libc/src/mathvec/generic/acoshf.cpp b/libc/src/mathvec/generic/acoshf.cpp
new file mode 100644
index 0000000000000..421a1c6d30ac6
--- /dev/null
+++ b/libc/src/mathvec/generic/acoshf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD acoshf vector 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/mathvec/acoshf.h"
+#include "src/__support/mathvec/acoshf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, acoshf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(acoshf)) {
+ return mathvec::acoshf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/asinhf.cpp b/libc/src/mathvec/generic/asinhf.cpp
new file mode 100644
index 0000000000000..22763de8d4e72
--- /dev/null
+++ b/libc/src/mathvec/generic/asinhf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD asinhf vector 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/mathvec/asinhf.h"
+#include "src/__support/mathvec/asinhf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, asinhf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(asinhf)) {
+ return mathvec::asinhf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/atanhf.cpp b/libc/src/mathvec/generic/atanhf.cpp
new file mode 100644
index 0000000000000..72ffb21723327
--- /dev/null
+++ b/libc/src/mathvec/generic/atanhf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD atanhf vector 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/mathvec/atanhf.h"
+#include "src/__support/mathvec/atanhf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, atanhf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(atanhf)) {
+ return mathvec::atanhf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index 5d5a42d551f46..2749047ba11c1 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -25,6 +25,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ acoshf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ acoshf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.acoshf
+ libc.src.mathvec.acoshf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
acospif_test
SUITE
@@ -59,6 +76,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ asinhf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ asinhf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.asinhf
+ libc.src.mathvec.asinhf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
asinpif_test
SUITE
@@ -93,6 +127,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ atanhf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ atanhf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.atanhf
+ libc.src.mathvec.atanhf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
cosf_test
SUITE
diff --git a/libc/test/src/mathvec/acoshf_test.cpp b/libc/test/src/mathvec/acoshf_test.cpp
new file mode 100644
index 0000000000000..887ddfe12be5f
--- /dev/null
+++ b/libc/test/src/mathvec/acoshf_test.cpp
@@ -0,0 +1,76 @@
+//===-- Unittests for acoshf ---------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/acoshf.h"
+#include "src/mathvec/acoshf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecAcoshfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using AcoshfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::acoshf,
+ LIBC_NAMESPACE::acoshf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecAcoshfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcoshfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<AcoshfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcoshfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AcoshfOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<AcoshfOp>(1.0f));
+}
+
+TEST_F(LlvmLibcVecAcoshfTest, SpecificBitPatterns) {
+ constexpr int N = 17;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f800000, // x = 1.0f
+ 0x45abaf26, // x = 0x1.575e4cp12f
+ 0x45dc6414, // x = 0x1.b8c828p12f
+ 0x49d29048, // x = 0x1.a5209p20f
+ 0x4bdd65a5, // x = 0x1.bacb4ap24f
+ 0x4c803f2c, // x = 0x1.007e58p26f
+ 0x4f8ffb03, // x = 0x1.1ff606p32f
+ 0x5c569e88, // x = 0x1.ad3d1p57f
+ 0x5e68984e, // x = 0x1.d1309cp61f
+ 0x62f7a05a, // x = 0x1.ef40b4p70f
+ 0x655890d3, // x = 0x1.b121a6p75f
+ 0x65de7ca6, // x = 0x1.bcf94cp76f
+ 0x6eb1a8ec, // x = 0x1.6351d8p94f
+ 0x71699003, // x = 0x1.d32006p99f
+ 0x76be09de, // x = 0x1.7c13bcp110f
+ 0x7967ec37, // x = 0x1.cfd86ep115f
+ 0x7997f30a, // x = 0x1.2fe614p116f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<AcoshfOp>(x, -x), wrap_vector<AcoshfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecAcoshfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, AcoshfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/asinhf_test.cpp b/libc/test/src/mathvec/asinhf_test.cpp
new file mode 100644
index 0000000000000..ec4c5e45a687a
--- /dev/null
+++ b/libc/test/src/mathvec/asinhf_test.cpp
@@ -0,0 +1,74 @@
+//===-- Unittests for asinhf ---------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/asinhf.h"
+#include "src/mathvec/asinhf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecAsinhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using AsinhfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::asinhf,
+ LIBC_NAMESPACE::asinhf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecAsinhfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AsinhfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<AsinhfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<AsinhfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<AsinhfOp>(0.0f));
+}
+
+TEST_F(LlvmLibcVecAsinhfTest, SpecificBitPatterns) {
+ constexpr int N = 17;
+ constexpr uint32_t INPUTS[N] = {
+ 0x45abaf26, // |x| = 0x1.575e4cp12f
+ 0x45e19b90, // |x| = 0x1.c3372p12f
+ 0x49d29048, // |x| = 0x1.a5209p20f
+ 0x4bdd65a5, // |x| = 0x1.bacb4ap24f
+ 0x4c803f2c, // |x| = 0x1.007e58p26f
+ 0x4f8ffb03, // |x| = 0x1.1ff606p32f
+ 0x58719e31, // |x| = 0x1.e33c62p49f
+ 0x5c569e88, // |x| = 0x1.ad3d1p57f
+ 0x5e68984e, // |x| = 0x1.d1309cp61f
+ 0x62f7a05a, // |x| = 0x1.ef40b4p70f
+ 0x655890d3, // |x| = 0x1.b121a6p75f
+ 0x65de7ca6, // |x| = 0x1.bcf94cp76f
+ 0x6eb1a8ec, // |x| = 0x1.6351d8p94f
+ 0x71699003, // |x| = 0x1.d32006p99f
+ 0x76be09de, // |x| = 0x1.7c13bcp110f
+ 0x7967ec37, // |x| = 0x1.cfd86ep115f
+ 0x7997f30a, // |x| = 0x1.2fe614p116f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<AsinhfOp>(x, -x), wrap_vector<AsinhfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecAsinhfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, AsinhfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/atanhf_test.cpp b/libc/test/src/mathvec/atanhf_test.cpp
new file mode 100644
index 0000000000000..5606814e79bcd
--- /dev/null
+++ b/libc/test/src/mathvec/atanhf_test.cpp
@@ -0,0 +1,53 @@
+//===-- Unittests for atanhf ---------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/atanhf.h"
+#include "src/mathvec/atanhf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using AtanhfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::atanhf,
+ LIBC_NAMESPACE::atanhf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecAtanhfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AtanhfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<AtanhfOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<AtanhfOp>(1.0f));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<AtanhfOp>(-1.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AtanhfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AtanhfOp>(neg_inf));
+
+ float x = FPBits(0x3f80'0001U).get_val();
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<AtanhfOp>(x, -x));
+}
+
+TEST_F(LlvmLibcVecAtanhfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, AtanhfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index 98dd2b90e9ad7..dfc2b4fa4f85b 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -25,6 +25,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ acoshf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ acoshf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.acoshf
+ libc.src.mathvec.acoshf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
acospif_test
NO_RUN_POSTBUILD
@@ -57,6 +73,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ asinhf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ asinhf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.asinhf
+ libc.src.mathvec.asinhf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
asinpif_test
NO_RUN_POSTBUILD
@@ -89,6 +121,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ atanhf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ atanhf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.atanhf
+ libc.src.mathvec.atanhf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
cosf_test
NO_RUN_POSTBUILD
diff --git a/libc/test/src/mathvec/exhaustive/acoshf_test.cpp b/libc/test/src/mathvec/exhaustive/acoshf_test.cpp
new file mode 100644
index 0000000000000..52e8a7afb6e85
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/acoshf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD acoshf -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/acoshf.h"
+#include "src/mathvec/acoshf.h"
+
+using LlvmLibcAcoshfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::acoshf,
+ LIBC_NAMESPACE::acoshf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcAcoshfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/asinhf_test.cpp b/libc/test/src/mathvec/exhaustive/asinhf_test.cpp
new file mode 100644
index 0000000000000..3b3de33182f1f
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/asinhf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD asinhf -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/asinhf.h"
+#include "src/mathvec/asinhf.h"
+
+using LlvmLibcAsinhfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::asinhf,
+ LIBC_NAMESPACE::asinhf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcAsinhfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/atanhf_test.cpp b/libc/test/src/mathvec/exhaustive/atanhf_test.cpp
new file mode 100644
index 0000000000000..06e8adb67844b
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/atanhf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD atanhf -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/atanhf.h"
+#include "src/mathvec/atanhf.h"
+
+using LlvmLibcAtanhfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::atanhf,
+ LIBC_NAMESPACE::atanhf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcAtanhfExhaustiveTest, EntireRange) { test_full_range_RN(); }
>From 5a654e7dd456dc497b1230303a909d72545d9036 Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 19:36:53 +0000
Subject: [PATCH 11/12] Add log1pf/log2f/log10f/logf as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 4 +
libc/config/linux/x86_64/entrypoints.txt | 4 +
libc/src/__support/mathvec/CMakeLists.txt | 36 +++++++
libc/src/__support/mathvec/log10f.h | 34 +++++++
libc/src/__support/mathvec/log1pf.h | 34 +++++++
libc/src/__support/mathvec/log2f.h | 34 +++++++
libc/src/__support/mathvec/logf.h | 34 +++++++
libc/src/mathvec/CMakeLists.txt | 4 +
libc/src/mathvec/generic/CMakeLists.txt | 56 +++++++++++
libc/src/mathvec/generic/log10f.cpp | 20 ++++
libc/src/mathvec/generic/log1pf.cpp | 20 ++++
libc/src/mathvec/generic/log2f.cpp | 20 ++++
libc/src/mathvec/generic/logf.cpp | 20 ++++
libc/src/mathvec/log10f.h | 20 ++++
libc/src/mathvec/log1pf.h | 20 ++++
libc/src/mathvec/log2f.h | 20 ++++
libc/src/mathvec/logf.h | 20 ++++
libc/test/src/mathvec/CMakeLists.txt | 68 ++++++++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 64 +++++++++++++
.../src/mathvec/exhaustive/log10f_test.cpp | 19 ++++
.../src/mathvec/exhaustive/log1pf_test.cpp | 19 ++++
.../src/mathvec/exhaustive/log2f_test.cpp | 19 ++++
.../test/src/mathvec/exhaustive/logf_test.cpp | 19 ++++
libc/test/src/mathvec/log10f_test.cpp | 80 ++++++++++++++++
libc/test/src/mathvec/log1pf_test.cpp | 89 ++++++++++++++++++
libc/test/src/mathvec/log2f_test.cpp | 61 ++++++++++++
libc/test/src/mathvec/logf_test.cpp | 94 +++++++++++++++++++
27 files changed, 932 insertions(+)
create mode 100644 libc/src/__support/mathvec/log10f.h
create mode 100644 libc/src/__support/mathvec/log1pf.h
create mode 100644 libc/src/__support/mathvec/log2f.h
create mode 100644 libc/src/__support/mathvec/logf.h
create mode 100644 libc/src/mathvec/generic/log10f.cpp
create mode 100644 libc/src/mathvec/generic/log1pf.cpp
create mode 100644 libc/src/mathvec/generic/log2f.cpp
create mode 100644 libc/src/mathvec/generic/logf.cpp
create mode 100644 libc/src/mathvec/log10f.h
create mode 100644 libc/src/mathvec/log1pf.h
create mode 100644 libc/src/mathvec/log2f.h
create mode 100644 libc/src/mathvec/logf.h
create mode 100644 libc/test/src/mathvec/exhaustive/log10f_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/log1pf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/log2f_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/logf_test.cpp
create mode 100644 libc/test/src/mathvec/log10f_test.cpp
create mode 100644 libc/test/src/mathvec/log1pf_test.cpp
create mode 100644 libc/test/src/mathvec/log2f_test.cpp
create mode 100644 libc/test/src/mathvec/logf_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 31bb10c497881..080fc99137c11 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1302,6 +1302,10 @@ if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
libc.src.mathvec.exp10m1f
libc.src.mathvec.expf
libc.src.mathvec.expm1f
+ libc.src.mathvec.log10f
+ libc.src.mathvec.log1pf
+ libc.src.mathvec.log2f
+ libc.src.mathvec.logf
libc.src.mathvec.sinf
libc.src.mathvec.sinhf
libc.src.mathvec.sinpif
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index b5f45cdc6bc3e..626b8e17af2af 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1525,6 +1525,10 @@ list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.exp10m1f
libc.src.mathvec.expf
libc.src.mathvec.expm1f
+ libc.src.mathvec.log10f
+ libc.src.mathvec.log1pf
+ libc.src.mathvec.log2f
+ libc.src.mathvec.logf
libc.src.mathvec.sinf
libc.src.mathvec.sinhf
libc.src.mathvec.sinpif
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index df817eaa1d9b0..5795ffe0b61ae 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -165,6 +165,42 @@ add_header_library(
libc.src.__support.math.expm1f
)
+add_header_library(
+ log10f
+ HDRS
+ log10f.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.log10f
+)
+
+add_header_library(
+ log1pf
+ HDRS
+ log1pf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.log1pf
+)
+
+add_header_library(
+ log2f
+ HDRS
+ log2f.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.log2f
+)
+
+add_header_library(
+ logf
+ HDRS
+ logf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.logf
+)
+
add_header_library(
sinf
HDRS
diff --git a/libc/src/__support/mathvec/log10f.h b/libc/src/__support/mathvec/log10f.h
new file mode 100644
index 0000000000000..a4c4a000398e9
--- /dev/null
+++ b/libc/src/__support/mathvec/log10f.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD log10f ------------------*- 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_MATHVEC_LOG10F_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_LOG10F_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/log10f.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> log10f(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::log10f(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_LOG10F_H
diff --git a/libc/src/__support/mathvec/log1pf.h b/libc/src/__support/mathvec/log1pf.h
new file mode 100644
index 0000000000000..b7400005b7e37
--- /dev/null
+++ b/libc/src/__support/mathvec/log1pf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD log1pf -----------------*- 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_MATHVEC_LOG1PF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_LOG1PF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/log1pf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> log1pf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::log1pf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_LOG1PF_H
diff --git a/libc/src/__support/mathvec/log2f.h b/libc/src/__support/mathvec/log2f.h
new file mode 100644
index 0000000000000..4974a5f6ec6b6
--- /dev/null
+++ b/libc/src/__support/mathvec/log2f.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD log2f ------------------*- 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_MATHVEC_LOG2F_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_LOG2F_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/log2f.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> log2f(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::log2f(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_LOG2F_H
diff --git a/libc/src/__support/mathvec/logf.h b/libc/src/__support/mathvec/logf.h
new file mode 100644
index 0000000000000..2687ebed6e57c
--- /dev/null
+++ b/libc/src/__support/mathvec/logf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD logf ------------------*- 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_MATHVEC_LOGF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_LOGF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/logf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> logf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::logf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_LOGF_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index 9a6bc238d4a1f..552dc9bcff4c1 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -66,6 +66,10 @@ add_vector_math_entrypoint_object(exp10f)
add_vector_math_entrypoint_object(exp10m1f)
add_vector_math_entrypoint_object(expf)
add_vector_math_entrypoint_object(expm1f)
+add_vector_math_entrypoint_object(log10f)
+add_vector_math_entrypoint_object(log1pf)
+add_vector_math_entrypoint_object(log2f)
+add_vector_math_entrypoint_object(logf)
add_vector_math_entrypoint_object(sinf)
add_vector_math_entrypoint_object(sinhf)
add_vector_math_entrypoint_object(sinpif)
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index 28c26e1d2cda1..eca112e2e6406 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -236,6 +236,62 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ log10f
+ SRCS
+ log10f.cpp
+ HDRS
+ ../log10f.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.log10f
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_entrypoint_object(
+ log1pf
+ SRCS
+ log1pf.cpp
+ HDRS
+ ../log1pf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.log1pf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_entrypoint_object(
+ log2f
+ SRCS
+ log2f.cpp
+ HDRS
+ ../log2f.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.log2f
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_entrypoint_object(
+ logf
+ SRCS
+ logf.cpp
+ HDRS
+ ../logf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.logf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
sinf
SRCS
diff --git a/libc/src/mathvec/generic/log10f.cpp b/libc/src/mathvec/generic/log10f.cpp
new file mode 100644
index 0000000000000..10835c620233c
--- /dev/null
+++ b/libc/src/mathvec/generic/log10f.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD log10f vector 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/mathvec/log10f.h"
+#include "src/__support/mathvec/log10f.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, log10f, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(log10f)) {
+ return mathvec::log10f(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/log1pf.cpp b/libc/src/mathvec/generic/log1pf.cpp
new file mode 100644
index 0000000000000..d905fcbc4a7d1
--- /dev/null
+++ b/libc/src/mathvec/generic/log1pf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD log1pf vector 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/mathvec/log1pf.h"
+#include "src/__support/mathvec/log1pf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, log1pf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(log1pf)) {
+ return mathvec::log1pf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/log2f.cpp b/libc/src/mathvec/generic/log2f.cpp
new file mode 100644
index 0000000000000..125711ed50aa2
--- /dev/null
+++ b/libc/src/mathvec/generic/log2f.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD log2f vector 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/mathvec/log2f.h"
+#include "src/__support/mathvec/log2f.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, log2f, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(log2f)) {
+ return mathvec::log2f(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/logf.cpp b/libc/src/mathvec/generic/logf.cpp
new file mode 100644
index 0000000000000..b3c9b60f64b34
--- /dev/null
+++ b/libc/src/mathvec/generic/logf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD logf vector 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/mathvec/logf.h"
+#include "src/__support/mathvec/logf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, logf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(logf)) {
+ return mathvec::logf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/log10f.h b/libc/src/mathvec/log10f.h
new file mode 100644
index 0000000000000..313db8a01b6e8
--- /dev/null
+++ b/libc/src/mathvec/log10f.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD log10f -------------------*- 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_MATHVEC_LOG10F_H
+#define LLVM_LIBC_SRC_MATHVEC_LOG10F_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> log10f(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_LOG10F_H
diff --git a/libc/src/mathvec/log1pf.h b/libc/src/mathvec/log1pf.h
new file mode 100644
index 0000000000000..8dd5ab37f219f
--- /dev/null
+++ b/libc/src/mathvec/log1pf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD log1pf -------------------*- 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_MATHVEC_LOG1PF_H
+#define LLVM_LIBC_SRC_MATHVEC_LOG1PF_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> log1pf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_LOG1PF_H
diff --git a/libc/src/mathvec/log2f.h b/libc/src/mathvec/log2f.h
new file mode 100644
index 0000000000000..4255c34d7361b
--- /dev/null
+++ b/libc/src/mathvec/log2f.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD log2f --------------------*- 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_MATHVEC_LOG2F_H
+#define LLVM_LIBC_SRC_MATHVEC_LOG2F_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> log2f(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_LOG2F_H
diff --git a/libc/src/mathvec/logf.h b/libc/src/mathvec/logf.h
new file mode 100644
index 0000000000000..f34a8b2c845b1
--- /dev/null
+++ b/libc/src/mathvec/logf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for SIMD logf --------------------*- 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_MATHVEC_LOGF_H
+#define LLVM_LIBC_SRC_MATHVEC_LOGF_H
+
+#include "src/__support/CPP/simd.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> logf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_LOGF_H
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index 2749047ba11c1..21c701f479d7d 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -301,6 +301,74 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ log10f_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ log10f_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.log10f
+ libc.src.mathvec.log10f
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_fp_unittest(
+ log1pf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ log1pf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.log1pf
+ libc.src.mathvec.log1pf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_fp_unittest(
+ log2f_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ log2f_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.log2f
+ libc.src.mathvec.log2f
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
+add_fp_unittest(
+ logf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ logf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.logf
+ libc.src.mathvec.logf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
sinf_test
SUITE
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index dfc2b4fa4f85b..6ea05a14e1b29 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -281,6 +281,70 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ log10f_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ log10f_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.log10f
+ libc.src.mathvec.log10f
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ log1pf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ log1pf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.log1pf
+ libc.src.mathvec.log1pf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ log2f_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ log2f_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.log2f
+ libc.src.mathvec.log2f
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
+add_fp_unittest(
+ logf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ logf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.logf
+ libc.src.mathvec.logf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
sinf_test
NO_RUN_POSTBUILD
diff --git a/libc/test/src/mathvec/exhaustive/log10f_test.cpp b/libc/test/src/mathvec/exhaustive/log10f_test.cpp
new file mode 100644
index 0000000000000..d418307bd668e
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/log10f_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD log10f -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/log10f.h"
+#include "src/mathvec/log10f.h"
+
+using LlvmLibcLog10fExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::log10f,
+ LIBC_NAMESPACE::log10f>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcLog10fExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/log1pf_test.cpp b/libc/test/src/mathvec/exhaustive/log1pf_test.cpp
new file mode 100644
index 0000000000000..959c39d1cb46d
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/log1pf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD log1pf ----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/log1pf.h"
+#include "src/mathvec/log1pf.h"
+
+using LlvmLibcLog1pfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::log1pf,
+ LIBC_NAMESPACE::log1pf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcLog1pfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/log2f_test.cpp b/libc/test/src/mathvec/exhaustive/log2f_test.cpp
new file mode 100644
index 0000000000000..3b7a0d1d1f1ee
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/log2f_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD log2f ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/log2f.h"
+#include "src/mathvec/log2f.h"
+
+using LlvmLibcLog2fExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::log2f,
+ LIBC_NAMESPACE::log2f>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcLog2fExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/logf_test.cpp b/libc/test/src/mathvec/exhaustive/logf_test.cpp
new file mode 100644
index 0000000000000..8a7371e89f2e1
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/logf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD logf ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/logf.h"
+#include "src/mathvec/logf.h"
+
+using LlvmLibcLogfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::logf,
+ LIBC_NAMESPACE::logf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcLogfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/log10f_test.cpp b/libc/test/src/mathvec/log10f_test.cpp
new file mode 100644
index 0000000000000..d18d9d49f1679
--- /dev/null
+++ b/libc/test/src/mathvec/log10f_test.cpp
@@ -0,0 +1,80 @@
+//===-- Unittests for log10f ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/log10f.h"
+#include "src/mathvec/log10f.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecLog10fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using Log10fOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::log10f,
+ LIBC_NAMESPACE::log10f>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecLog10fTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Log10fOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Log10fOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Log10fOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<Log10fOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Log10fOp>(1.0f));
+}
+
+TEST_F(LlvmLibcVecLog10fTest, TrickyInputs) {
+ constexpr int N = 21;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f800000U /*1.0f*/,
+ 0x41200000U /*10.0f*/,
+ 0x42c80000U /*100.0f*/,
+ 0x447a0000U /*1,000.0f*/,
+ 0x461c4000U /*10,000.0f*/,
+ 0x47c35000U /*100,000.0f*/,
+ 0x49742400U /*1,000,000.0f*/,
+ 0x4b189680U /*10,000,000.0f*/,
+ 0x4cbebc20U /*100,000,000.0f*/,
+ 0x4e6e6b28U /*1,000,000,000.0f*/,
+ 0x501502f9U /*10,000,000,000.0f*/,
+ 0x4f134f83U /*2471461632.0f*/,
+ 0x7956ba5eU /*69683218960000541503257137270226944.0f*/,
+ 0x08ae'a356U /*0x1.5d46acp-110f*/,
+ 0x1c7d'a337U /*0x1.fb466ep-71f*/,
+ 0x69c8'c583U /*0x1.918b06p+84f*/,
+ 0x0efe'ee7aU /*0x1.fddcf4p-98f*/,
+ 0x3f5f'de1bU /*0x1.bfbc36p-1f*/,
+ 0x3f80'70d8U /*0x1.00e1bp0f*/,
+ 0x120b'93dcU /*0x1.1727b8p-91f*/,
+ 0x13ae'78d3U /*0x1.5cf1a6p-88f*/,
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Log10fOp>(x, -x), wrap_vector<Log10fOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecLog10fTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, Log10fOp);
+ }
+}
diff --git a/libc/test/src/mathvec/log1pf_test.cpp b/libc/test/src/mathvec/log1pf_test.cpp
new file mode 100644
index 0000000000000..423bc8976689c
--- /dev/null
+++ b/libc/test/src/mathvec/log1pf_test.cpp
@@ -0,0 +1,89 @@
+//===-- Unittests for log1pf ---------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/log1pf.h"
+#include "src/mathvec/log1pf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecLog1pfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using Log1pfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::log1pf,
+ LIBC_NAMESPACE::log1pf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecLog1pfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Log1pfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Log1pfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Log1pfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Log1pfOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<Log1pfOp>(-1.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Log1pfOp>(-2.0f));
+}
+
+TEST_F(LlvmLibcVecLog1pfTest, TrickyInputs) {
+ constexpr int N = 28;
+ constexpr uint32_t INPUTS[N] = {
+ 0x35c00006U, /*0x1.80000cp-20f*/
+ 0x35400003U, /*0x1.800006p-21f*/
+ 0x3640000cU, /*0x1.800018p-19f*/
+ 0x36c00018U, /*0x1.80003p-18f*/
+ 0x3710001bU, /*0x1.200036p-17f*/
+ 0x37400030U, /*0x1.80006p-17f*/
+ 0x3770004bU, /*0x1.e00096p-17f*/
+ 0x3b9315c8U, /*0x1.262b9p-8f*/
+ 0x3c6eb7afU, /*0x1.dd6f5ep-7f*/
+ 0x3ddbfec3U, /*0x1.b7fd86p-4f*/
+ 0x3efd81adU, /*0x1.fb035ap-2f*/
+ 0x41078febU, /*0x1.0f1fd6p+3f*/
+ 0x4cc1c80bU, /*0x1.839016p+26f*/
+ 0x55185f82U, /*0x1.30bf04p+43f*/
+ 0x5cd69e88U, /*0x1.ad3d1p+58f*/
+ 0x5ee8984eU, /*0x1.d1309cp+62f*/
+ 0x65d890d3U, /*0x1.b121a6p+76f*/
+ 0x665e7ca6U, /*0x1.bcf94cp+77f*/
+ 0x6f31a8ecU, /*0x1.6351d8p+95f*/
+ 0x79e7ec37U, /*0x1.cfd86ep+116f*/
+ 0x7a17f30aU, /*0x1.2fe614p+117f*/
+ 0xb53ffffdU, /*-0x1.7ffffap-21f*/
+ 0xb70fffe5U, /*-0x1.1fffcap-17f*/
+ 0xbb0ec8c4U, /*-0x1.1d9188p-9f*/
+ 0xbc4d092cU, /*-0x1.9a1258p-7f*/
+ 0xbc657728U, /*-0x1.caee5p-7f*/
+ 0xbd1d20afU, /*-0x1.3a415ep-5f*/
+ 0xbf800000U, /*-1.0f*/
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Log1pfOp>(x, -x), wrap_vector<Log1pfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecLog1pfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, Log1pfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/log2f_test.cpp b/libc/test/src/mathvec/log2f_test.cpp
new file mode 100644
index 0000000000000..c4d4ae73cf751
--- /dev/null
+++ b/libc/test/src/mathvec/log2f_test.cpp
@@ -0,0 +1,61 @@
+//===-- Unittests for log2f -----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/log2f.h"
+#include "src/mathvec/log2f.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecLog2fTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using Log2fOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::log2f,
+ LIBC_NAMESPACE::log2f>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecLog2fTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<Log2fOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Log2fOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<Log2fOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<Log2fOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<Log2fOp>(1.0f));
+}
+
+TEST_F(LlvmLibcVecLog2fTest, TrickyInputs) {
+ constexpr int N = 10;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f7d'57f5U, 0x3f7e'3274U, 0x3f7e'd848U, 0x3f7f'd6ccU, 0x3f7f'ffffU,
+ 0x3f80'079bU, 0x3f81'd0b5U, 0x3f82'e602U, 0x3f83'c98dU, 0x3f8c'ba39U,
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<Log2fOp>(x, -x), wrap_vector<Log2fOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecLog2fTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, Log2fOp);
+ }
+}
diff --git a/libc/test/src/mathvec/logf_test.cpp b/libc/test/src/mathvec/logf_test.cpp
new file mode 100644
index 0000000000000..4dbfd70a63b38
--- /dev/null
+++ b/libc/test/src/mathvec/logf_test.cpp
@@ -0,0 +1,94 @@
+//===-- Unittests for logf -----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/logf.h"
+#include "src/mathvec/logf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecLogfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using LogfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::logf,
+ LIBC_NAMESPACE::logf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecLogfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<LogfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<LogfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<LogfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<LogfOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<LogfOp>(1.0f));
+}
+
+TEST_F(LlvmLibcVecLogfTest, TrickyInputs) {
+ constexpr int N = 35;
+ constexpr uint32_t INPUTS[N] = {
+ 0x1b7679ffU, /*0x1.ecf3fep-73f*/
+ 0x1e88452dU, /*0x1.108a5ap-66f*/
+ 0x3f800001U, /*0x1.000002p+0f*/
+ 0x3509dcf6U, /*0x1.13b9ecp-21f*/
+ 0x3bf86ef0U, /*0x1.f0ddep-8f*/
+ 0x3c413d3aU, /*0x1.827a74p-7f*/
+ 0x3ca1c99fU, /*0x1.43933ep-6f*/
+ 0x3d13e105U, /*0x1.27c20ap-5f*/
+ 0x3f7ff1f2U, /*0x1.ffe3e4p-1f*/
+ 0x3f7fffffU, /*0x1.fffffep-1f*/
+ 0x3f800001U, /*0x1.000002p+0f*/
+ 0x3f800006U, /*0x1.00000cp+0f*/
+ 0x3f800014U, /*0x1.000028p+0f*/
+ 0x3f80001cU, /*0x1.000038p+0f*/
+ 0x3f80c777U, /*0x1.018eeep+0f*/
+ 0x3f80ce72U, /*0x1.019ce4p+0f*/
+ 0x3f80d19fU, /*0x1.01a33ep+0f*/
+ 0x3f80f7bfU, /*0x1.01ef7ep+0f*/
+ 0x3f80fcfeU, /*0x1.01f9fcp+0f*/
+ 0x3f81feb4U, /*0x1.03fd68p+0f*/
+ 0x3f83d731U, /*0x1.07ae62p+0f*/
+ 0x3f90cb1dU, /*0x1.21963ap+0f*/
+ 0x3fc55379U, /*0x1.8aa6f2p+0f*/
+ 0x3fd364d7U, /*0x1.a6c9aep+0f*/
+ 0x41178febU, /*0x1.2f1fd6p+3f*/
+ 0x4c5d65a5U, /*0x1.bacb4ap+25f*/
+ 0x4e85f412U, /*0x1.0be824p+30f*/
+ 0x500ffb03U, /*0x1.1ff606p+33f*/
+ 0x5cd69e88U, /*0x1.ad3d1p+58f*/
+ 0x5ee8984eU, /*0x1.d1309cp+62f*/
+ 0x65d890d3U, /*0x1.b121a6p+76f*/
+ 0x665e7ca6U, /*0x1.bcf94cp+77f*/
+ 0x6f31a8ecU, /*0x1.6351d8p+95f*/
+ 0x79e7ec37U, /*0x1.cfd86ep+116f*/
+ 0x7a17f30aU, /*0x1.2fe614p+117f*/
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<LogfOp>(x, -x), wrap_vector<LogfOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecLogfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, LogfOp);
+ }
+}
>From 10ef47b7396acfd047e695f0f02450b89ca0920e Mon Sep 17 00:00:00 2001
From: Dylan Fleming <Dylan.Fleming at arm.com>
Date: Fri, 22 May 2026 19:43:23 +0000
Subject: [PATCH 12/12] Add erff/rsqrtf/sqrtf/cbrtf as loop over scalar
---
libc/config/linux/aarch64/entrypoints.txt | 4 ++
libc/config/linux/x86_64/entrypoints.txt | 4 ++
libc/src/__support/mathvec/CMakeLists.txt | 36 ++++++++++
libc/src/__support/mathvec/cbrtf.h | 34 ++++++++++
libc/src/__support/mathvec/erff.h | 34 ++++++++++
libc/src/__support/mathvec/rsqrtf.h | 34 ++++++++++
libc/src/__support/mathvec/sqrtf.h | 34 ++++++++++
libc/src/mathvec/CMakeLists.txt | 4 ++
libc/src/mathvec/cbrtf.h | 21 ++++++
libc/src/mathvec/erff.h | 21 ++++++
libc/src/mathvec/generic/CMakeLists.txt | 56 +++++++++++++++
libc/src/mathvec/generic/cbrtf.cpp | 20 ++++++
libc/src/mathvec/generic/erff.cpp | 20 ++++++
libc/src/mathvec/generic/rsqrtf.cpp | 20 ++++++
libc/src/mathvec/generic/sqrtf.cpp | 20 ++++++
libc/src/mathvec/rsqrtf.h | 21 ++++++
libc/src/mathvec/sqrtf.h | 21 ++++++
libc/test/src/mathvec/CMakeLists.txt | 68 +++++++++++++++++++
libc/test/src/mathvec/cbrtf_test.cpp | 55 +++++++++++++++
libc/test/src/mathvec/erff_test.cpp | 59 ++++++++++++++++
.../src/mathvec/exhaustive/CMakeLists.txt | 64 +++++++++++++++++
.../src/mathvec/exhaustive/cbrtf_test.cpp | 19 ++++++
.../test/src/mathvec/exhaustive/erff_test.cpp | 19 ++++++
.../src/mathvec/exhaustive/rsqrtf_test.cpp | 19 ++++++
.../src/mathvec/exhaustive/sqrtf_test.cpp | 19 ++++++
libc/test/src/mathvec/rsqrtf_test.cpp | 50 ++++++++++++++
libc/test/src/mathvec/sqrtf_test.cpp | 48 +++++++++++++
27 files changed, 824 insertions(+)
create mode 100644 libc/src/__support/mathvec/cbrtf.h
create mode 100644 libc/src/__support/mathvec/erff.h
create mode 100644 libc/src/__support/mathvec/rsqrtf.h
create mode 100644 libc/src/__support/mathvec/sqrtf.h
create mode 100644 libc/src/mathvec/cbrtf.h
create mode 100644 libc/src/mathvec/erff.h
create mode 100644 libc/src/mathvec/generic/cbrtf.cpp
create mode 100644 libc/src/mathvec/generic/erff.cpp
create mode 100644 libc/src/mathvec/generic/rsqrtf.cpp
create mode 100644 libc/src/mathvec/generic/sqrtf.cpp
create mode 100644 libc/src/mathvec/rsqrtf.h
create mode 100644 libc/src/mathvec/sqrtf.h
create mode 100644 libc/test/src/mathvec/cbrtf_test.cpp
create mode 100644 libc/test/src/mathvec/erff_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/cbrtf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/erff_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/rsqrtf_test.cpp
create mode 100644 libc/test/src/mathvec/exhaustive/sqrtf_test.cpp
create mode 100644 libc/test/src/mathvec/rsqrtf_test.cpp
create mode 100644 libc/test/src/mathvec/sqrtf_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 080fc99137c11..48af7964c2130 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1293,9 +1293,11 @@ if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
libc.src.mathvec.asinpif
libc.src.mathvec.atanf
libc.src.mathvec.atanhf
+ libc.src.mathvec.cbrtf
libc.src.mathvec.cosf
libc.src.mathvec.coshf
libc.src.mathvec.cospif
+ libc.src.mathvec.erff
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
libc.src.mathvec.exp10f
@@ -1306,9 +1308,11 @@ if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
libc.src.mathvec.log1pf
libc.src.mathvec.log2f
libc.src.mathvec.logf
+ libc.src.mathvec.rsqrtf
libc.src.mathvec.sinf
libc.src.mathvec.sinhf
libc.src.mathvec.sinpif
+ libc.src.mathvec.sqrtf
libc.src.mathvec.tanf
libc.src.mathvec.tanhf
libc.src.mathvec.tanpif
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 626b8e17af2af..b3b1c463e9c12 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1516,9 +1516,11 @@ list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.asinpif
libc.src.mathvec.atanf
libc.src.mathvec.atanhf
+ libc.src.mathvec.cbrtf
libc.src.mathvec.cosf
libc.src.mathvec.coshf
libc.src.mathvec.cospif
+ libc.src.mathvec.erff
libc.src.mathvec.exp2f
libc.src.mathvec.exp2m1f
libc.src.mathvec.exp10f
@@ -1529,9 +1531,11 @@ list(APPEND TARGET_LIBMVEC_ENTRYPOINTS
libc.src.mathvec.log1pf
libc.src.mathvec.log2f
libc.src.mathvec.logf
+ libc.src.mathvec.rsqrtf
libc.src.mathvec.sinf
libc.src.mathvec.sinhf
libc.src.mathvec.sinpif
+ libc.src.mathvec.sqrtf
libc.src.mathvec.tanf
libc.src.mathvec.tanhf
libc.src.mathvec.tanpif
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
index 5795ffe0b61ae..5fcb2feb2f4a8 100644
--- a/libc/src/__support/mathvec/CMakeLists.txt
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -72,6 +72,15 @@ add_header_library(
libc.src.__support.math.atanhf
)
+add_header_library(
+ cbrtf
+ HDRS
+ cbrtf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.cbrtf
+)
+
add_header_library(
cosf
HDRS
@@ -99,6 +108,15 @@ add_header_library(
libc.src.__support.math.cospif
)
+add_header_library(
+ erff
+ HDRS
+ erff.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.erff
+)
+
add_header_library(
exp2f
HDRS
@@ -201,6 +219,15 @@ add_header_library(
libc.src.__support.math.logf
)
+add_header_library(
+ rsqrtf
+ HDRS
+ rsqrtf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.rsqrtf
+)
+
add_header_library(
sinf
HDRS
@@ -228,6 +255,15 @@ add_header_library(
libc.src.__support.math.sinpif
)
+add_header_library(
+ sqrtf
+ HDRS
+ sqrtf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.math.sqrtf
+)
+
add_header_library(
tanf
HDRS
diff --git a/libc/src/__support/mathvec/cbrtf.h b/libc/src/__support/mathvec/cbrtf.h
new file mode 100644
index 0000000000000..f57f20c9b2c52
--- /dev/null
+++ b/libc/src/__support/mathvec/cbrtf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD cbrtf ------------------*- 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_MATHVEC_CBRTF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_CBRTF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/cbrtf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> cbrtf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::cbrtf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_CBRTF_H
diff --git a/libc/src/__support/mathvec/erff.h b/libc/src/__support/mathvec/erff.h
new file mode 100644
index 0000000000000..0800818b348dc
--- /dev/null
+++ b/libc/src/__support/mathvec/erff.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD erff ------------------*- 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_MATHVEC_ERFF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_ERFF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/erff.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> erff(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::erff(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_ERFF_H
diff --git a/libc/src/__support/mathvec/rsqrtf.h b/libc/src/__support/mathvec/rsqrtf.h
new file mode 100644
index 0000000000000..319096970aea8
--- /dev/null
+++ b/libc/src/__support/mathvec/rsqrtf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD rsqrtf ------------------*- 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_MATHVEC_RSQRTF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_RSQRTF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/rsqrtf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> rsqrtf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::rsqrtf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_RSQRTF_H
diff --git a/libc/src/__support/mathvec/sqrtf.h b/libc/src/__support/mathvec/sqrtf.h
new file mode 100644
index 0000000000000..1f5b6cb6405ba
--- /dev/null
+++ b/libc/src/__support/mathvec/sqrtf.h
@@ -0,0 +1,34 @@
+//===-- Implementation header for SIMD sqrtf ------------------*- 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_MATHVEC_SQRTF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_SQRTF_H
+
+#include "src/__support/CPP/simd.h"
+#define LIBC_MATH (LIBC_MATH_NO_ERRNO | LIBC_MATH_NO_EXCEPT)
+#include "src/__support/math/sqrtf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> sqrtf(cpp::simd<float, N> x) {
+ cpp::simd<float, N> result;
+
+ for (size_t i = 0; i < N; ++i)
+ result[i] = math::sqrtf(x[i]);
+
+ return result;
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_SQRTF_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
index 552dc9bcff4c1..b51ee8d97a230 100644
--- a/libc/src/mathvec/CMakeLists.txt
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -57,9 +57,11 @@ add_vector_math_entrypoint_object(asinhf)
add_vector_math_entrypoint_object(asinpif)
add_vector_math_entrypoint_object(atanf)
add_vector_math_entrypoint_object(atanhf)
+add_vector_math_entrypoint_object(cbrtf)
add_vector_math_entrypoint_object(cosf)
add_vector_math_entrypoint_object(coshf)
add_vector_math_entrypoint_object(cospif)
+add_vector_math_entrypoint_object(erff)
add_vector_math_entrypoint_object(exp2f)
add_vector_math_entrypoint_object(exp2m1f)
add_vector_math_entrypoint_object(exp10f)
@@ -70,9 +72,11 @@ add_vector_math_entrypoint_object(log10f)
add_vector_math_entrypoint_object(log1pf)
add_vector_math_entrypoint_object(log2f)
add_vector_math_entrypoint_object(logf)
+add_vector_math_entrypoint_object(rsqrtf)
add_vector_math_entrypoint_object(sinf)
add_vector_math_entrypoint_object(sinhf)
add_vector_math_entrypoint_object(sinpif)
+add_vector_math_entrypoint_object(sqrtf)
add_vector_math_entrypoint_object(tanf)
add_vector_math_entrypoint_object(tanhf)
add_vector_math_entrypoint_object(tanpif)
diff --git a/libc/src/mathvec/cbrtf.h b/libc/src/mathvec/cbrtf.h
new file mode 100644
index 0000000000000..55d9f7843f0c1
--- /dev/null
+++ b/libc/src/mathvec/cbrtf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD cbrtf --------------------*- 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_MATHVEC_CBRTF_H
+#define LLVM_LIBC_SRC_MATHVEC_CBRTF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> cbrtf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_CBRTF_H
diff --git a/libc/src/mathvec/erff.h b/libc/src/mathvec/erff.h
new file mode 100644
index 0000000000000..dcb4985a25bac
--- /dev/null
+++ b/libc/src/mathvec/erff.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD erff --------------------*- 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_MATHVEC_ERFF_H
+#define LLVM_LIBC_SRC_MATHVEC_ERFF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> erff(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_ERFF_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
index eca112e2e6406..7f49ad2ad90dc 100644
--- a/libc/src/mathvec/generic/CMakeLists.txt
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -110,6 +110,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ cbrtf
+ SRCS
+ cbrtf.cpp
+ HDRS
+ ../cbrtf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.cbrtf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
cosf
SRCS
@@ -152,6 +166,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ erff
+ SRCS
+ erff.cpp
+ HDRS
+ ../erff.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.erff
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
exp2f
SRCS
@@ -292,6 +320,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ rsqrtf
+ SRCS
+ rsqrtf.cpp
+ HDRS
+ ../rsqrtf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.rsqrtf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
sinf
SRCS
@@ -334,6 +376,20 @@ add_entrypoint_object(
FMA_OPT
)
+add_entrypoint_object(
+ sqrtf
+ SRCS
+ sqrtf.cpp
+ HDRS
+ ../sqrtf.h
+ DEPENDS
+ libc.src.mathvec.abi_prefix
+ libc.src.__support.mathvec.sqrtf
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_entrypoint_object(
tanf
SRCS
diff --git a/libc/src/mathvec/generic/cbrtf.cpp b/libc/src/mathvec/generic/cbrtf.cpp
new file mode 100644
index 0000000000000..bb8b1c2dd3d37
--- /dev/null
+++ b/libc/src/mathvec/generic/cbrtf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD cbrt vector 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/mathvec/cbrtf.h"
+#include "src/__support/mathvec/cbrtf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, cbrtf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(cbrtf)) {
+ return mathvec::cbrtf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/erff.cpp b/libc/src/mathvec/generic/erff.cpp
new file mode 100644
index 0000000000000..95a5c396bedc7
--- /dev/null
+++ b/libc/src/mathvec/generic/erff.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD erf vector 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/mathvec/erff.h"
+#include "src/__support/mathvec/erff.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, erff, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(erff)) {
+ return mathvec::erff(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/rsqrtf.cpp b/libc/src/mathvec/generic/rsqrtf.cpp
new file mode 100644
index 0000000000000..19ac61d8e267d
--- /dev/null
+++ b/libc/src/mathvec/generic/rsqrtf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD rsqrt vector 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/mathvec/rsqrtf.h"
+#include "src/__support/mathvec/rsqrtf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, rsqrtf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(rsqrtf)) {
+ return mathvec::rsqrtf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/generic/sqrtf.cpp b/libc/src/mathvec/generic/sqrtf.cpp
new file mode 100644
index 0000000000000..6b8ce2a62daf4
--- /dev/null
+++ b/libc/src/mathvec/generic/sqrtf.cpp
@@ -0,0 +1,20 @@
+//===-- Single-precision SIMD sqrt vector 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/mathvec/sqrtf.h"
+#include "src/__support/mathvec/sqrtf.h"
+#include "src/mathvec/abi_prefix.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, sqrtf, (cpp::simd<float> x),
+ LIBC_VFABI_FLOAT_SYMBOL(sqrtf)) {
+ return mathvec::sqrtf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/mathvec/rsqrtf.h b/libc/src/mathvec/rsqrtf.h
new file mode 100644
index 0000000000000..3ffbaf375b432
--- /dev/null
+++ b/libc/src/mathvec/rsqrtf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD rsqrtf -------------------*- 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_MATHVEC_RSQRTF_H
+#define LLVM_LIBC_SRC_MATHVEC_RSQRTF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> rsqrtf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_RSQRTF_H
diff --git a/libc/src/mathvec/sqrtf.h b/libc/src/mathvec/sqrtf.h
new file mode 100644
index 0000000000000..2a81414c8e30e
--- /dev/null
+++ b/libc/src/mathvec/sqrtf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD sqrtf --------------------*- 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_MATHVEC_SQRTF_H
+#define LLVM_LIBC_SRC_MATHVEC_SQRTF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> sqrtf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_SQRTF_H
diff --git a/libc/test/src/mathvec/CMakeLists.txt b/libc/test/src/mathvec/CMakeLists.txt
index 21c701f479d7d..c924b3894f9b7 100644
--- a/libc/test/src/mathvec/CMakeLists.txt
+++ b/libc/test/src/mathvec/CMakeLists.txt
@@ -144,6 +144,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ cbrtf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ cbrtf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.cbrtf
+ libc.src.mathvec.cbrtf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
cosf_test
SUITE
@@ -199,6 +216,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ erff_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ erff_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.erff
+ libc.src.mathvec.erff
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
exp2f_test
SUITE
@@ -369,6 +403,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ rsqrtf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ rsqrtf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.rsqrtf
+ libc.src.mathvec.rsqrtf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
sinf_test
SUITE
@@ -424,6 +475,23 @@ add_fp_unittest(
FMA_OPT
)
+add_fp_unittest(
+ sqrtf_test
+ SUITE
+ libc-mathvec-unittests
+ SRCS
+ sqrtf_test.cpp
+ DEPENDS
+ .unit_test_wrappers
+ libc.src.math.sqrtf
+ libc.src.mathvec.sqrtf
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
+
add_fp_unittest(
tanf_test
SUITE
diff --git a/libc/test/src/mathvec/cbrtf_test.cpp b/libc/test/src/mathvec/cbrtf_test.cpp
new file mode 100644
index 0000000000000..bd30efc4cf821
--- /dev/null
+++ b/libc/test/src/mathvec/cbrtf_test.cpp
@@ -0,0 +1,55 @@
+//===-- Unittests for cbrtf -----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/cbrtf.h"
+#include "src/mathvec/cbrtf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecCbrtfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using CbrtfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::cbrtf,
+ LIBC_NAMESPACE::cbrtf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecCbrtfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<CbrtfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<CbrtfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<CbrtfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<CbrtfOp>(0.0f));
+}
+
+TEST_F(LlvmLibcVecCbrtfTest, SpecialValues) {
+ constexpr float INPUTS[] = {
+ 0x1.60451p2f, 0x1.31304cp1f, 0x1.d17cp2f, 0x1.bp-143f, 0x1.338cp2f,
+ };
+
+ for (float x : INPUTS)
+ EXPECT_SIMD_EQ(wrap_ref<CbrtfOp>(x, -x), wrap_vector<CbrtfOp>(x, -x));
+}
+
+TEST_F(LlvmLibcVecCbrtfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, CbrtfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/erff_test.cpp b/libc/test/src/mathvec/erff_test.cpp
new file mode 100644
index 0000000000000..cce58a92e49da
--- /dev/null
+++ b/libc/test/src/mathvec/erff_test.cpp
@@ -0,0 +1,59 @@
+//===-- Unittests for erff ------------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/erff.h"
+#include "src/mathvec/erff.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecErffTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using ErffOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::erff,
+ LIBC_NAMESPACE::erff>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecErffTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<ErffOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(1.0f), wrap_vector<ErffOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(-1.0f), wrap_vector<ErffOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<ErffOp>(0.0f));
+}
+
+TEST_F(LlvmLibcVecErffTest, TrickyInputs) {
+ constexpr int N = 2;
+ constexpr uint32_t INPUTS[N] = {
+ 0x3f65'9229U, // |x| = 0x1.cb2452p-1f
+ 0x4004'1e6aU, // |x| = 0x1.083cd4p+1f
+ };
+
+ for (int i = 0; i < N; ++i) {
+ float x = FPBits(INPUTS[i]).get_val();
+ EXPECT_SIMD_EQ(wrap_ref<ErffOp>(x, -x), wrap_vector<ErffOp>(x, -x));
+ }
+}
+
+TEST_F(LlvmLibcVecErffTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, ErffOp);
+ }
+}
diff --git a/libc/test/src/mathvec/exhaustive/CMakeLists.txt b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
index 6ea05a14e1b29..1d986125bff19 100644
--- a/libc/test/src/mathvec/exhaustive/CMakeLists.txt
+++ b/libc/test/src/mathvec/exhaustive/CMakeLists.txt
@@ -137,6 +137,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ cbrtf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ cbrtf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.cbrtf
+ libc.src.mathvec.cbrtf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
cosf_test
NO_RUN_POSTBUILD
@@ -185,6 +201,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ erff_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ erff_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.erff
+ libc.src.mathvec.erff
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
exp2f_test
NO_RUN_POSTBUILD
@@ -345,6 +377,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ rsqrtf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ rsqrtf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.rsqrtf
+ libc.src.mathvec.rsqrtf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
sinf_test
NO_RUN_POSTBUILD
@@ -393,6 +441,22 @@ add_fp_unittest(
-lpthread
)
+add_fp_unittest(
+ sqrtf_test
+ NO_RUN_POSTBUILD
+ SUITE
+ libc-mathvec-exhaustivetests
+ SRCS
+ sqrtf_test.cpp
+ DEPENDS
+ .exhaustive_test
+ libc.src.math.sqrtf
+ libc.src.mathvec.sqrtf
+ libc.src.__support.CPP.simd
+ LINK_LIBRARIES
+ -lpthread
+)
+
add_fp_unittest(
tanf_test
NO_RUN_POSTBUILD
diff --git a/libc/test/src/mathvec/exhaustive/cbrtf_test.cpp b/libc/test/src/mathvec/exhaustive/cbrtf_test.cpp
new file mode 100644
index 0000000000000..6cec5ea83b313
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/cbrtf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD cbrtf ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/cbrtf.h"
+#include "src/mathvec/cbrtf.h"
+
+using LlvmLibcCbrtfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::cbrtf,
+ LIBC_NAMESPACE::cbrtf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcCbrtfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/erff_test.cpp b/libc/test/src/mathvec/exhaustive/erff_test.cpp
new file mode 100644
index 0000000000000..5b9ce891db8b5
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/erff_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD erff -------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/erff.h"
+#include "src/mathvec/erff.h"
+
+using LlvmLibcErffExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::erff,
+ LIBC_NAMESPACE::erff>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcErffExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/rsqrtf_test.cpp b/libc/test/src/mathvec/exhaustive/rsqrtf_test.cpp
new file mode 100644
index 0000000000000..f06b04e9eed32
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/rsqrtf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD rsqrtf -----------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/rsqrtf.h"
+#include "src/mathvec/rsqrtf.h"
+
+using LlvmLibcRsqrtfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::rsqrtf,
+ LIBC_NAMESPACE::rsqrtf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcRsqrtfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/exhaustive/sqrtf_test.cpp b/libc/test/src/mathvec/exhaustive/sqrtf_test.cpp
new file mode 100644
index 0000000000000..9d1b0e44efa88
--- /dev/null
+++ b/libc/test/src/mathvec/exhaustive/sqrtf_test.cpp
@@ -0,0 +1,19 @@
+//===-- Exhaustive test for SIMD sqrtf ------------------------------------===//
+//
+// 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 "exhaustive_test.h"
+#include "src/__support/CPP/simd.h"
+#include "src/math/sqrtf.h"
+#include "src/mathvec/sqrtf.h"
+
+using LlvmLibcSqrtfExhaustiveTest =
+ LlvmLibcUnaryOpExhaustiveMathvecTest<float, LIBC_NAMESPACE::sqrtf,
+ LIBC_NAMESPACE::sqrtf>;
+
+// Tests all possible 32-bit input patterns
+TEST_F(LlvmLibcSqrtfExhaustiveTest, EntireRange) { test_full_range_RN(); }
diff --git a/libc/test/src/mathvec/rsqrtf_test.cpp b/libc/test/src/mathvec/rsqrtf_test.cpp
new file mode 100644
index 0000000000000..07d76e41b0af2
--- /dev/null
+++ b/libc/test/src/mathvec/rsqrtf_test.cpp
@@ -0,0 +1,50 @@
+//===-- Unittests for rsqrtf ----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/rsqrtf.h"
+#include "src/mathvec/rsqrtf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecRsqrtfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using RsqrtfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::rsqrtf,
+ LIBC_NAMESPACE::rsqrtf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecRsqrtfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<RsqrtfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<RsqrtfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<RsqrtfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<RsqrtfOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(neg_inf), wrap_vector<RsqrtfOp>(-0.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<RsqrtfOp>(-1.0f));
+}
+
+TEST_F(LlvmLibcVecRsqrtfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, RsqrtfOp);
+ }
+}
diff --git a/libc/test/src/mathvec/sqrtf_test.cpp b/libc/test/src/mathvec/sqrtf_test.cpp
new file mode 100644
index 0000000000000..80c9cb6a59336
--- /dev/null
+++ b/libc/test/src/mathvec/sqrtf_test.cpp
@@ -0,0 +1,48 @@
+//===-- Unittests for sqrtf -----------------------------------------------===//
+//
+// 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/math_macros.h"
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/math/sqrtf.h"
+#include "src/mathvec/sqrtf.h"
+#include "test/UnitTest/SIMDMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "test/src/mathvec/UnitTestWrappers.h"
+
+#include "hdr/stdint_proxy.h"
+
+using LlvmLibcVecSqrtfTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+using SqrtfOp =
+ LIBC_NAMESPACE::testing::mathvec::UnaryOp<float, LIBC_NAMESPACE::sqrtf,
+ LIBC_NAMESPACE::sqrtf>;
+using LIBC_NAMESPACE::cpp::splat;
+using LIBC_NAMESPACE::testing::mathvec::wrap_ref;
+using LIBC_NAMESPACE::testing::mathvec::wrap_vector;
+
+TEST_F(LlvmLibcVecSqrtfTest, SpecialNumbers) {
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SqrtfOp>(aNaN));
+
+ EXPECT_SIMD_EQ(splat(inf), wrap_vector<SqrtfOp>(inf));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SqrtfOp>(neg_inf));
+
+ EXPECT_SIMD_EQ(splat(0.0f), wrap_vector<SqrtfOp>(0.0f));
+
+ EXPECT_SIMD_EQ(splat(aNaN), wrap_vector<SqrtfOp>(-1.0f));
+}
+
+TEST_F(LlvmLibcVecSqrtfTest, InFloatRange) {
+ constexpr uint32_t COUNT = 100'000;
+ constexpr uint32_t STEP = 0x7f80'0000U / COUNT;
+ for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
+ float x = FPBits(v).get_val();
+ TEST_VARIED_CASES(x, SqrtfOp);
+ }
+}
More information about the libc-commits
mailing list