[libc-commits] [libc] [libc][mathvec] Initial commit for LIBC vector math component (PR #173058)
via libc-commits
libc-commits at lists.llvm.org
Fri Dec 19 09:49:31 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: None (DylanFleming-arm)
<details>
<summary>Changes</summary>
Created mathvec directories and unittest framework for vector math functions, as well as an initial implementation of vector expf, which is presently CR for round-to-nearest.
---
Patch is 28.43 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/173058.diff
20 Files Affected:
- (modified) libc/CMakeLists.txt (+2)
- (modified) libc/config/linux/aarch64/entrypoints.txt (+7)
- (modified) libc/config/linux/x86_64/entrypoints.txt (+7)
- (modified) libc/lib/CMakeLists.txt (+3-3)
- (modified) libc/src/CMakeLists.txt (+5)
- (modified) libc/src/__support/CMakeLists.txt (+3)
- (added) libc/src/__support/mathvec/CMakeLists.txt (+35)
- (added) libc/src/__support/mathvec/common_constants.h (+40)
- (added) libc/src/__support/mathvec/expf.h (+76)
- (added) libc/src/__support/mathvec/expf_utils.h (+29)
- (added) libc/src/__support/mathvec/vector_utils.h (+46)
- (added) libc/src/mathvec/CMakeLists.txt (+43)
- (added) libc/src/mathvec/expf.h (+21)
- (added) libc/src/mathvec/generic/CMakeLists.txt (+12)
- (added) libc/src/mathvec/generic/expf.cpp (+18)
- (added) libc/test/UnitTest/SIMDMatcher.h (+61)
- (modified) libc/test/src/CMakeLists.txt (+4)
- (added) libc/test/src/mathvec/AddTest.h (+87)
- (added) libc/test/src/mathvec/CMakeLists.txt (+14)
- (added) libc/test/src/mathvec/expf_test.cpp (+133)
``````````diff
diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index 4e6b4195a9c5e..2d474f08841ca 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -350,6 +350,7 @@ include(LLVMLibCRules)
set(TARGET_LLVMLIBC_ENTRYPOINTS "")
set(TARGET_LIBC_ENTRYPOINTS "")
set(TARGET_LIBM_ENTRYPOINTS "")
+set(TARGET_LIBMVEC_ENTRYPOINTS "")
set(TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS "")
# Check entrypoints.txt
@@ -380,6 +381,7 @@ foreach(removed_entrypoint IN LISTS TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS)
list(REMOVE_ITEM TARGET_LLVMLIBC_ENTRYPOINTS ${removed_entrypoint})
list(REMOVE_ITEM TARGET_LIBC_ENTRYPOINTS ${removed_entrypoint})
list(REMOVE_ITEM TARGET_LIBM_ENTRYPOINTS ${removed_entrypoint})
+ list(REMOVE_ITEM TARGET_LIBMVEC_ENTRYPOINTS ${removed_entrypoint})
endforeach()
set(TARGET_ENTRYPOINT_NAME_LIST "")
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 970c825bbfc96..d0db8b0acff2b 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1178,7 +1178,14 @@ if(LLVM_LIBC_FULL_BUILD)
)
endif()
+if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
+ set(TARGET_LIBMVEC_ENTRYPOINTS
+ libc.src.mathvec.expf
+ )
+endif()
+
set(TARGET_LLVMLIBC_ENTRYPOINTS
${TARGET_LIBC_ENTRYPOINTS}
${TARGET_LIBM_ENTRYPOINTS}
+ ${TARGET_LIBMVEC_ENTRYPOINTS}
)
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 9399b284fa2da..7c5e649968223 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1396,7 +1396,14 @@ if(LLVM_LIBC_FULL_BUILD)
)
endif()
+if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
+ set(TARGET_LIBMVEC_ENTRYPOINTS
+ libc.src.mathvec.expf
+ )
+endif()
+
set(TARGET_LLVMLIBC_ENTRYPOINTS
${TARGET_LIBC_ENTRYPOINTS}
${TARGET_LIBM_ENTRYPOINTS}
+ ${TARGET_LIBMVEC_ENTRYPOINTS}
)
diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index ce0b07fb6cb49..19751a9cc0736 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -2,10 +2,10 @@ set(libc_archive_targets "")
set(libc_archive_names "")
set(libc_archive_entrypoint_lists "")
if(LLVM_LIBC_FULL_BUILD)
- list(APPEND libc_archive_names c m)
- list(APPEND libc_archive_targets libc libm)
+ list(APPEND libc_archive_names c m mvec)
+ list(APPEND libc_archive_targets libc libm libmvec)
list(APPEND libc_archive_entrypoint_lists
- TARGET_LIBC_ENTRYPOINTS TARGET_LIBM_ENTRYPOINTS)
+ TARGET_LIBC_ENTRYPOINTS TARGET_LIBM_ENTRYPOINTS TARGET_LIBMVEC_ENTRYPOINTS)
else()
list(APPEND libc_archive_names llvmlibc)
list(APPEND libc_archive_targets libc)
diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index b2afe0a33acee..8f005a700a80f 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -29,6 +29,11 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
add_subdirectory(termios)
endif()
+if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
+ message(STATUS "Vector math enabled")
+ add_subdirectory(mathvec)
+endif()
+
if(NOT LLVM_LIBC_FULL_BUILD)
return()
endif()
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index c7f127d6934a0..1ebd7dd2621a2 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -416,3 +416,6 @@ if(NOT (LIBC_TARGET_OS_IS_DARWIN))
endif()
add_subdirectory(math)
+if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
+ add_subdirectory(mathvec)
+endif()
diff --git a/libc/src/__support/mathvec/CMakeLists.txt b/libc/src/__support/mathvec/CMakeLists.txt
new file mode 100644
index 0000000000000..4b6e31ad29929
--- /dev/null
+++ b/libc/src/__support/mathvec/CMakeLists.txt
@@ -0,0 +1,35 @@
+add_header_library(
+ common_constants
+ HDRS
+ common_constants.h
+ DEPENDS
+)
+
+add_header_library(
+ expf_utils
+ HDRS
+ expf_utils.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ libc.src.__support.mathvec.common_constants
+)
+
+add_header_library(
+ expf
+ HDRS
+ expf.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.CPP.simd
+ libc.src.__support.FPUtil.FPBits
+ libc.src.__support.mathvec.expf_utils
+ libc.src.__support.mathvec.vector_utils
+)
+
+add_header_library(
+ vector_utils
+ HDRS
+ vector_utils.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+)
diff --git a/libc/src/__support/mathvec/common_constants.h b/libc/src/__support/mathvec/common_constants.h
new file mode 100644
index 0000000000000..c235d6842e5b0
--- /dev/null
+++ b/libc/src/__support/mathvec/common_constants.h
@@ -0,0 +1,40 @@
+//===-- Common constants for mathvec functions ------------------*- 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_COMMON_CONSTANTS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_COMMON_CONSTANTS_H
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace common_constants_internal {
+
+// Lookup table for mantissas of 2^(i / 64) with i = 0, ..., 63.
+static constexpr uint64_t EXP_MANTISSA[64] = {
+ 0x0000000000000, 0x02c9a3e778061, 0x059b0d3158574, 0x0874518759bc8,
+ 0x0b5586cf9890f, 0x0e3ec32d3d1a2, 0x11301d0125b51, 0x1429aaea92de0,
+ 0x172b83c7d517b, 0x1a35beb6fcb75, 0x1d4873168b9aa, 0x2063b88628cd6,
+ 0x2387a6e756238, 0x26b4565e27cdd, 0x29e9df51fdee1, 0x2d285a6e4030b,
+ 0x306fe0a31b715, 0x33c08b26416ff, 0x371a7373aa9cb, 0x3a7db34e59ff7,
+ 0x3dea64c123422, 0x4160a21f72e2a, 0x44e086061892d, 0x486a2b5c13cd0,
+ 0x4bfdad5362a27, 0x4f9b2769d2ca7, 0x5342b569d4f82, 0x56f4736b527da,
+ 0x5ab07dd485429, 0x5e76f15ad2148, 0x6247eb03a5585, 0x6623882552225,
+ 0x6a09e667f3bcd, 0x6dfb23c651a2f, 0x71f75e8ec5f74, 0x75feb564267c9,
+ 0x7a11473eb0187, 0x7e2f336cf4e62, 0x82589994cce13, 0x868d99b4492ed,
+ 0x8ace5422aa0db, 0x8f1ae99157736, 0x93737b0cdc5e5, 0x97d829fde4e50,
+ 0x9c49182a3f090, 0xa0c667b5de565, 0xa5503b23e255d, 0xa9e6b5579fdbf,
+ 0xae89f995ad3ad, 0xb33a2b84f15fb, 0xb7f76f2fb5e47, 0xbcc1e904bc1d2,
+ 0xc199bdd85529c, 0xc67f12e57d14b, 0xcb720dcef9069, 0xd072d4a07897c,
+ 0xd5818dcfba487, 0xda9e603db3285, 0xdfc97337b9b5f, 0xe502ee78b3ff6,
+ 0xea4afa2a490da, 0xefa1bee615a27, 0xf50765b6e4540, 0xfa7c1819e90d8,
+};
+
+} // namespace common_constants_internal
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_COMMON_CONSTANTS_H
diff --git a/libc/src/__support/mathvec/expf.h b/libc/src/__support/mathvec/expf.h
new file mode 100644
index 0000000000000..6b5abb4a0c32f
--- /dev/null
+++ b/libc/src/__support/mathvec/expf.h
@@ -0,0 +1,76 @@
+//===-- Implementation header for SIMD expf ---------------------*- 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_EXPF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXPF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/common.h"
+#include "src/__support/mathvec/expf_utils.h"
+#include "src/__support/mathvec/vector_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace mathvec {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<double, N> inline_exp(cpp::simd<double, N> x) {
+ static constexpr cpp::simd<double, N> shift = 0x1.800000000ffc0p+46;
+
+ auto z = shift + x * 0x1.71547652b82fep+0;
+ auto n = z - shift;
+
+ auto r = x;
+ r = r - n * 0x1.62e42fefa3800p-1;
+ r = r - n * 0x1.ef35793c76730p-45;
+
+ /* y = exp(r) - 1 ~= r + C0 r^2 + C1 r^3 + C2 r^4 + C3 r^5. */
+ static constexpr cpp::simd<double, N> c0 = 0x1.fffffffffdbcdp-2;
+ static constexpr cpp::simd<double, N> c1 = 0x1.555555555444cp-3;
+ static constexpr cpp::simd<double, N> c2 = 0x1.555573c6a9f7dp-5;
+ static constexpr cpp::simd<double, N> c3 = 0x1.1111266d28935p-7;
+
+ auto r2 = r * r;
+ auto p01 = c0 + r * c1;
+ auto p23 = c2 + r * c3;
+ auto p04 = p01 + r2 * p23;
+ auto y = r + p04 * r2;
+
+ auto u = reinterpret_cast<cpp::simd<uint64_t, N>>(z);
+ auto s = exp_lookup(u);
+ return s + s * y;
+}
+
+template <size_t N>
+LIBC_INLINE cpp::simd<float, N> expf(cpp::simd<float, N> x) {
+ using FPBits = typename fputil::FPBits<float>;
+ cpp::simd<float, N> ret;
+
+ auto is_inf = cpp::simd_cast<bool>(x >= 0x1.62e38p+9);
+ auto is_zero = cpp::simd_cast<bool>(x <= -0x1.628c2ap+9);
+ auto is_special = is_inf | is_zero;
+
+ auto special_res =
+ cpp::select(is_inf, cpp::simd<float, N>(FPBits::inf().get_val()),
+ cpp::simd<float>(0.0f));
+
+ auto [lo, hi] = vector_float_to_double(x);
+
+ auto lo_res = inline_exp(lo);
+ auto hi_res = inline_exp(hi);
+
+ ret = vector_double_to_float(lo_res, hi_res);
+ return cpp::select(is_special, special_res, ret);
+}
+
+} // namespace mathvec
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXPF_H
diff --git a/libc/src/__support/mathvec/expf_utils.h b/libc/src/__support/mathvec/expf_utils.h
new file mode 100644
index 0000000000000..2650bcba9bca7
--- /dev/null
+++ b/libc/src/__support/mathvec/expf_utils.h
@@ -0,0 +1,29 @@
+//===-- Common utils for exp function ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP_UTILS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP_UTILS_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/mathvec/common_constants.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+template <size_t N>
+LIBC_INLINE cpp::simd<double, N> exp_lookup(cpp::simd<uint64_t, N> u) {
+ auto index = u & cpp::simd<uint64_t, N>(0x3f);
+ auto mantissa = cpp::gather<cpp::simd<uint64_t, N>>(
+ true, index, common_constants_internal::EXP_MANTISSA);
+ auto exponent = (u >> 6) << 52;
+ auto result = mantissa | exponent;
+ return reinterpret_cast<cpp::simd<double, N>>(result);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP_UTILS_H
diff --git a/libc/src/__support/mathvec/vector_utils.h b/libc/src/__support/mathvec/vector_utils.h
new file mode 100644
index 0000000000000..d2138f148a0ee
--- /dev/null
+++ b/libc/src/__support/mathvec/vector_utils.h
@@ -0,0 +1,46 @@
+//===-- Common utils for SIMD functions -------------------------*- 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_VECTOR_UTILS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_VECTOR_UTILS_H
+
+#include "src/__support/CPP/simd.h"
+#include <tuple>
+
+namespace LIBC_NAMESPACE_DECL {
+
+// Casts a simd<float, N> into two simd<double, N/2>
+template <size_t N>
+LIBC_INLINE constexpr auto vector_float_to_double(cpp::simd<float, N> v) {
+ static_assert(N % 2 == 0, "vector size must be even");
+ constexpr size_t H = N / 2;
+
+ auto parts = cpp::split<H, H>(v);
+ auto lo_f = cpp::get<0>(parts);
+ auto hi_f = cpp::get<1>(parts);
+
+ auto lo_d = cpp::simd_cast<double, float, H>(lo_f);
+ auto hi_d = cpp::simd_cast<double, float, H>(hi_f);
+
+ return cpp::make_tuple(lo_d, hi_d);
+}
+
+// Casts two simd<double, N> into a simd<float, 2N>
+template <size_t N>
+LIBC_INLINE constexpr auto vector_double_to_float(cpp::simd<double, N> lo_d,
+ cpp::simd<double, N> hi_d) {
+
+ auto lo_f = cpp::simd_cast<float, double, N>(lo_d);
+ auto hi_f = cpp::simd_cast<float, double, N>(hi_d);
+
+ return cpp::concat(lo_f, hi_f);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATHVEC_VECTOR_UTILS_H
diff --git a/libc/src/mathvec/CMakeLists.txt b/libc/src/mathvec/CMakeLists.txt
new file mode 100644
index 0000000000000..dff1dd3b70b51
--- /dev/null
+++ b/libc/src/mathvec/CMakeLists.txt
@@ -0,0 +1,43 @@
+add_subdirectory(generic)
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
+ add_subdirectory(${LIBC_TARGET_ARCHITECTURE})
+endif()
+
+function(add_vector_math_entrypoint_object name)
+ # We prefer machine specific implementation if available. Hence we check
+ # that first and return early if we are able to add an alias target for the
+ # machine specific implementation.
+ get_fq_target_name("${LIBC_TARGET_ARCHITECTURE}.${name}" fq_machine_specific_target_name)
+ if(TARGET ${fq_machine_specific_target_name})
+ add_entrypoint_object(
+ ${name}
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_ARCHITECTURE}.${name}
+ )
+ return()
+ endif()
+
+ get_fq_target_name("generic.${name}" fq_generic_target_name)
+ if(TARGET ${fq_generic_target_name})
+ add_entrypoint_object(
+ ${name}
+ ALIAS
+ DEPENDS
+ .generic.${name}
+ )
+ return()
+ endif()
+
+ # Add a dummy entrypoint object for missing implementations. They will be skipped
+ # anyway as there will be no entry for them in the target entrypoints list.
+ add_entrypoint_object(
+ ${name}
+ SRCS
+ dummy_srcs
+ HDRS
+ dummy_hdrs
+ )
+endfunction()
+
+add_vector_math_entrypoint_object(expf)
diff --git a/libc/src/mathvec/expf.h b/libc/src/mathvec/expf.h
new file mode 100644
index 0000000000000..257fb485838af
--- /dev/null
+++ b/libc/src/mathvec/expf.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for SIMD expf ---------------------*- 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_EXPF_H
+#define LLVM_LIBC_SRC_MATHVEC_EXPF_H
+
+#include "src/__support/CPP/simd.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+cpp::simd<float> expf(cpp::simd<float> x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATHVEC_EXPF_H
diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt
new file mode 100644
index 0000000000000..769794d6d5eee
--- /dev/null
+++ b/libc/src/mathvec/generic/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_entrypoint_object(
+ expf
+ SRCS
+ expf.cpp
+ HDRS
+ ../expf.h
+ DEPENDS
+ libc.src.__support.CPP.simd
+ FLAGS
+ ROUND_OPT
+ FMA_OPT
+)
diff --git a/libc/src/mathvec/generic/expf.cpp b/libc/src/mathvec/generic/expf.cpp
new file mode 100644
index 0000000000000..2e113d17e8680
--- /dev/null
+++ b/libc/src/mathvec/generic/expf.cpp
@@ -0,0 +1,18 @@
+//===-- Single-precision SIMD e^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/expf.h"
+#include "src/__support/mathvec/expf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(cpp::simd<float>, expf, (cpp::simd<float> x)) {
+ return mathvec::expf(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/UnitTest/SIMDMatcher.h b/libc/test/UnitTest/SIMDMatcher.h
new file mode 100644
index 0000000000000..542d311ddbd89
--- /dev/null
+++ b/libc/test/UnitTest/SIMDMatcher.h
@@ -0,0 +1,61 @@
+//===-- SIMDMatchers.h ------------------------------------------*- 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_UNITTEST_SIMDMATCHER_H
+#define LLVM_LIBC_TEST_UNITTEST_SIMDMATCHER_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/architectures.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include "hdr/math_macros.h"
+
+#define EXPECT_SIMD_EQ(REF, RES) \
+ for (size_t i = 0; \
+ i < LIBC_NAMESPACE::cpp::internal::native_vector_size<float>; i++) { \
+ EXPECT_FP_EQ(REF[i], RES[i]); \
+ }
+
+#define EXPECT_SIMD_EQ_WITH_EXCEPTION(REF, RES, EXCEPTION) \
+ for (size_t i = 0; \
+ i < LIBC_NAMESPACE::cpp::internal::native_vector_size<float>; i++) { \
+ EXPECT_FP_EQ_WITH_EXCEPTION(REF[i], RES[i], EXCEPTION); \
+ }
+
+#define EXPECT_SIMD_EQ_ROUNDING_MODE(expected, actual, rounding_mode) \
+ do { \
+ using namespace LIBC_NAMESPACE::fputil::testing; \
+ ForceRoundingMode __r((rounding_mode)); \
+ if (__r.success) { \
+ EXPECT_SIMD_EQ((expected), (actual)) \
+ } \
+ } while (0)
+
+#define EXPECT_SIMD_EQ_ROUNDING_NEAREST(expected, actual) \
+ EXPECT_SIMD_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::Nearest)
+
+#define EXPECT_SIMD_EQ_ROUNDING_UPWARD(expected, actual) \
+ EXPECT_SIMD_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::Upward)
+
+#define EXPECT_SIMD_EQ_ROUNDING_DOWNWARD(expected, actual) \
+ EXPECT_SIMD_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::Downward)
+
+#define EXPECT_SIMD_EQ_ROUNDING_TOWARD_ZERO(expected, actual) \
+ EXPECT_SIMD_EQ_ROUNDING_MODE((expected), (actual), RoundingMode::TowardZero)
+
+#define EXPECT_SIMD_EQ_ALL_ROUNDING(expected, actual) \
+ do { \
+ EXPECT_SIMD_EQ_ROUNDING_NEAREST((expected), (actual)); \
+ EXPECT_SIMD_EQ_ROUNDING_UPWARD((expected), (actual)); \
+ EXPECT_SIMD_EQ_ROUNDING_DOWNWARD((expected), (actual)); \
+ EXPECT_SIMD_EQ_ROUNDING_TOWARD_ZERO((expected), (actual)); \
+ } while (0)
+
+#endif // LLVM_LIBC_TEST_UNITTEST_SIMDMATCHER_H
diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 0c6ec9f07a9b7..5e61c739c066a 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -87,6 +87,10 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
add_subdirectory(termios)
endif()
+if(LIBC_COMPILER_HAS_EXT_VECTOR_TYPE)
+ add_subdirectory(mathvec)
+endif()
+
if(NOT LLVM_LIBC_FULL_BUILD)
return()
endif()
diff --git a/libc/test/src/mathvec/AddTest.h b/libc/test/src/mathvec/AddTest.h
new file mode 100644
index 0000000000000..2f7d0ec6904e3
--- /dev/null
+++ b/libc/test/src/mathvec/AddTest.h
@@ -0,0 +1,87 @@
+//===-- Utility class to test different flavors of float add ----*- 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_ADDTEST_H
+#define LLVM_LIBC_TEST_SRC_MATHVEC_ADDTEST_H
+
+#include "src/__support/CPP/algorithm.h"
+#incl...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/173058
More information about the libc-commits
mailing list