[libcxx-commits] [libcxx] [libc++][SIMD] Add native SIMD width detection for HVX (PR #183432)
Brian Cain via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Feb 25 17:49:28 PST 2026
https://github.com/androm3da created https://github.com/llvm/llvm-project/pull/183432
None
>From 179fbe5f73e2c63494562ed6faf6e8a11d8303f8 Mon Sep 17 00:00:00 2001
From: Brian Cain <brian.cain at oss.qualcomm.com>
Date: Wed, 25 Feb 2026 17:14:00 -0800
Subject: [PATCH 1/2] [libc++][SIMD] Generalize __vec_ext ABI tag validity
limit
The is_abi_tag_v upper bound for __vec_ext<N> was hardcoded to 32,
which matches max_fixed_size. However, native<T> for targets with
wide vector registers (e.g. 128-byte HVX, 64-byte AVX-512) can
produce __vec_ext<N> with N > 32 for small element types like char.
Derive the limit from _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES so that
native<T> always produces a valid ABI tag, while preserving the
existing behavior on targets where the native width is <= 32 bytes.
---
libcxx/include/experimental/__simd/vec_ext.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/experimental/__simd/vec_ext.h b/libcxx/include/experimental/__simd/vec_ext.h
index 2a4b8c748f86d..9bd806f098b0c 100644
--- a/libcxx/include/experimental/__simd/vec_ext.h
+++ b/libcxx/include/experimental/__simd/vec_ext.h
@@ -33,7 +33,8 @@ struct __vec_ext {
} // namespace simd_abi
template <int _Np>
-inline constexpr bool is_abi_tag_v<simd_abi::__vec_ext<_Np>> = _Np > 0 && _Np <= 32;
+inline constexpr bool is_abi_tag_v<simd_abi::__vec_ext<_Np>> =
+ _Np > 0 && _Np <= (_LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES > 32 ? _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES : 32);
template <class _Tp, int _Np>
struct __simd_storage<_Tp, simd_abi::__vec_ext<_Np>> {
>From 29d3756a297d33ec809430096ae895e5fca32724 Mon Sep 17 00:00:00 2001
From: Brian Cain <brian.cain at oss.qualcomm.com>
Date: Wed, 25 Feb 2026 17:38:34 -0800
Subject: [PATCH 2/2] [libc++][SIMD] Add native SIMD width detection for HVX
Set _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES to 128 when targeting Hexagon
HVX (-mhvx). This makes native_simd map to full-width HVX vector
registers (e.g. native_simd<int>::size() == 32).
Only 128-byte HVX mode is supported for now; compiling with
-mhvx-length=64B produces a diagnostic.
Add simd_size_hvx.pass.cpp that verifies native_simd sizes match the
128-byte HVX vector register width.
---
libcxx/include/__cxx03/experimental/__config | 7 ++-
.../include/experimental/__simd/declaration.h | 7 ++-
.../simd/simd.traits/simd_size_hvx.pass.cpp | 45 +++++++++++++++++++
3 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 libcxx/test/std/experimental/simd/simd.traits/simd_size_hvx.pass.cpp
diff --git a/libcxx/include/__cxx03/experimental/__config b/libcxx/include/__cxx03/experimental/__config
index 027522ed35771..71ec7f5dd9503 100644
--- a/libcxx/include/__cxx03/experimental/__config
+++ b/libcxx/include/__cxx03/experimental/__config
@@ -36,7 +36,12 @@
}
// TODO: support more targets
-#if defined(__AVX__)
+#if defined(__HVX__)
+# if __HVX_LENGTH__ != 128
+# error "Only 128-byte HVX vectors are supported by <experimental/simd>"
+# endif
+# define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 128
+#elif defined(__AVX__)
# define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 32
#else
# define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 16
diff --git a/libcxx/include/experimental/__simd/declaration.h b/libcxx/include/experimental/__simd/declaration.h
index d9395baecfe0f..88751c5586cb2 100644
--- a/libcxx/include/experimental/__simd/declaration.h
+++ b/libcxx/include/experimental/__simd/declaration.h
@@ -16,7 +16,12 @@
#if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
// TODO: support more targets
-# if defined(__AVX__)
+# if defined(__HVX__)
+# if __HVX_LENGTH__ != 128
+# error "Only 128-byte HVX vectors are supported by <experimental/simd>"
+# endif
+# define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 128
+# elif defined(__AVX__)
# define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 32
# else
# define _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES 16
diff --git a/libcxx/test/std/experimental/simd/simd.traits/simd_size_hvx.pass.cpp b/libcxx/test/std/experimental/simd/simd.traits/simd_size_hvx.pass.cpp
new file mode 100644
index 0000000000000..9887081e5da00
--- /dev/null
+++ b/libcxx/test/std/experimental/simd/simd.traits/simd_size_hvx.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// REQUIRES: hexagon-registered-target
+// ADDITIONAL_COMPILE_FLAGS: -mhvx
+
+// <experimental/simd>
+//
+// [simd.traits]
+// Verify that native_simd sizes match the 128-byte HVX vector register
+// width. This mirrors the checks in simd_size.pass.cpp for the native
+// ABI but with concrete HVX expectations.
+
+#include "../test_utils.h"
+
+namespace ex = std::experimental::parallelism_v2;
+
+static_assert(_LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES == 128, "HVX native SIMD width must be 128 bytes");
+
+struct CheckHvxNativeSimdSize {
+ template <class T>
+ void operator()() {
+ constexpr std::size_t expected = 128 / sizeof(T);
+
+ static_assert(ex::simd_size_v<T, ex::simd_abi::native<T>> == expected);
+ static_assert(ex::simd_size<T, ex::simd_abi::native<T>>::value == expected);
+ static_assert(ex::native_simd<T>::size() == expected);
+ static_assert(ex::is_abi_tag_v<ex::simd_abi::native<T>>);
+
+ // memory_alignment for native should be 128 bytes (one HVX register)
+ if constexpr (!std::is_same_v<T, long double>)
+ static_assert(ex::memory_alignment_v<ex::native_simd<T>> == 128);
+ }
+};
+
+int main(int, char**) {
+ types::for_each(arithmetic_no_bool_types(), CheckHvxNativeSimdSize());
+ return 0;
+}
More information about the libcxx-commits
mailing list