[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