[libc-commits] [libc] [libc] Implement generic SIMD helper 'simd.h' and implement strlen (PR #152605)
Nikolas Klauser via libc-commits
libc-commits at lists.llvm.org
Thu Aug 28 01:53:49 PDT 2025
================
@@ -0,0 +1,233 @@
+//===-- Portable SIMD library similar to stdx::simd -------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a generic interface into fixed-size SIMD instructions
+// using the clang vector type. The API shares some similarities with the
+// stdx::simd proposal, but instead chooses to use vectors as primitive types
+// with several extra helper functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/algorithm.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/type_traits/integral_constant.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+#include <stddef.h>
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_CPP_SIMD_H
+#define LLVM_LIBC_SRC___SUPPORT_CPP_SIMD_H
+
+namespace LIBC_NAMESPACE_DECL {
+namespace cpp {
+
+static_assert(LIBC_HAS_VECTOR_TYPE, "compiler does not support vector types");
+
+namespace internal {
+
+template <size_t Size> struct get_as_integer_type;
+
+template <> struct get_as_integer_type<1> {
+ using type = uint8_t;
+};
+template <> struct get_as_integer_type<2> {
+ using type = uint16_t;
+};
+template <> struct get_as_integer_type<4> {
+ using type = uint32_t;
+};
+template <> struct get_as_integer_type<8> {
+ using type = uint64_t;
+};
+
+template <class T>
+using get_as_integer_type_t = typename get_as_integer_type<sizeof(T)>::type;
+
+#if defined(LIBC_TARGET_CPU_HAS_AVX512F)
+template <typename T>
+inline constexpr size_t native_vector_size = 64 / sizeof(T);
+#elif defined(LIBC_TARGET_CPU_HAS_AVX2)
+template <typename T>
+inline constexpr size_t native_vector_size = 32 / sizeof(T);
+#elif defined(LIBC_TARGET_CPU_HAS_SSE2) || defined(LIBC_TARGET_CPU_HAS_ARM_NEON)
+template <typename T>
+inline constexpr size_t native_vector_size = 16 / sizeof(T);
+#else
+template <typename T> inline constexpr size_t native_vector_size = 1;
+#endif
+} // namespace internal
+
+// Type aliases.
+template <typename T, size_t N>
+using fixed_size_simd = T [[clang::ext_vector_type(N)]];
+template <typename T, size_t N = internal::native_vector_size<T>>
+using simd = T [[clang::ext_vector_type(N)]];
+template <typename T>
+using simd_mask = simd<bool, internal::native_vector_size<T>>;
+
+// Type trait helpers.
+template <typename T> struct simd_size : cpp::integral_constant<size_t, 1> {};
+template <typename T, unsigned N>
+struct simd_size<T [[clang::ext_vector_type(N)]]>
+ : cpp::integral_constant<size_t, N> {};
----------------
philnik777 wrote:
```suggestion
template <typename T, unsigned N>
struct simd_size<simd<T, N>>
: cpp::integral_constant<size_t, N> {};
```
should also work.
https://github.com/llvm/llvm-project/pull/152605
More information about the libc-commits
mailing list