[libcxx-commits] [libcxx] [libc++] Run vector instructions during constant evaluation when Clang supports it (PR #160057)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Mon Sep 22 02:54:59 PDT 2025


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/160057

None

>From 7bc832208aa2d7808393aa56eef7999a1c67ece1 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Mon, 22 Sep 2025 11:54:40 +0200
Subject: [PATCH] [libc++] Run vector instructions during constant evaluation
 when Clang supports it

---
 libcxx/include/__algorithm/mismatch.h   |  2 +-
 libcxx/include/__algorithm/simd_utils.h | 21 ++++++++++++++++++---
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index a6836792c0581..b8a791bf976e2 100644
--- a/libcxx/include/__algorithm/mismatch.h
+++ b/libcxx/include/__algorithm/mismatch.h
@@ -65,7 +65,7 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
   constexpr size_t __vec_size     = __native_vector_size<__value_type>;
   using __vec                     = __simd_vector<__value_type, __vec_size>;
 
-  if (!__libcpp_is_constant_evaluated()) {
+  if (!__libcpp_is_constant_evaluated() || _LIBCPP_HAS_CONSTEXPR_VECTORS) {
     auto __orig_first1 = __first1;
     auto __last2       = __first2 + (__last1 - __first1);
     while (static_cast<size_t>(__last1 - __first1) >= __unroll_count * __vec_size) [[__unlikely__]] {
diff --git a/libcxx/include/__algorithm/simd_utils.h b/libcxx/include/__algorithm/simd_utils.h
index 96b074c063a5d..65317fe35c7bd 100644
--- a/libcxx/include/__algorithm/simd_utils.h
+++ b/libcxx/include/__algorithm/simd_utils.h
@@ -40,6 +40,12 @@ _LIBCPP_PUSH_MACROS
 
 #if _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS
 
+#  if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2200
+#    define _LIBCPP_HAS_CONSTEXPR_VECTORS 1
+#  else
+#    define _LIBCPP_HAS_CONSTEXPR_VECTORS 0
+#  endif
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
@@ -123,15 +129,23 @@ template <class _Tp, size_t _Np>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_set(__simd_vector<_Tp, _Np> __vec) noexcept {
   using __mask_vec = __simd_vector<bool, _Np>;
 
+#  if _LIBCPP_HAS_CONSTEXPR_VECTORS
+#if defined(_LIBCPP_BIG_ENDIAN)
+  return __builtin_clzg(__builtin_convertvector(__vec, __mask_vec), static_cast<int>(_Np));
+#else
+  return __builtin_ctzg(__builtin_convertvector(__vec, __mask_vec), static_cast<int>(_Np));
+#endif
+#  else
+
   // This has MSan disabled du to https://llvm.org/PR85876
   auto __impl = [&]<class _MaskT>(_MaskT) _LIBCPP_NO_SANITIZE("memory") noexcept {
-#  if defined(_LIBCPP_BIG_ENDIAN)
+#    if defined(_LIBCPP_BIG_ENDIAN)
     return std::min<size_t>(
         _Np, std::__countl_zero(__builtin_bit_cast(_MaskT, __builtin_convertvector(__vec, __mask_vec))));
-#  else
+#    else
     return std::min<size_t>(
         _Np, std::__countr_zero(__builtin_bit_cast(_MaskT, __builtin_convertvector(__vec, __mask_vec))));
-#  endif
+#    endif
   };
 
   if constexpr (sizeof(__mask_vec) == sizeof(uint8_t)) {
@@ -146,6 +160,7 @@ template <class _Tp, size_t _Np>
     static_assert(sizeof(__mask_vec) == 0, "unexpected required size for mask integer type");
     return 0;
   }
+#  endif
 }
 
 template <class _Tp, size_t _Np>



More information about the libcxx-commits mailing list