[libcxx-commits] [libcxx] [libcxx] enable AltiVec vectorization with element-wise comparison wrapper (PR #207832)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jul 6 22:18:17 PDT 2026
https://github.com/Himadhith updated https://github.com/llvm/llvm-project/pull/207832
>From 451c89af5f6abf5927e6cbf0620e78479399694a Mon Sep 17 00:00:00 2001
From: himadhith <himadhith.v at ibm.com>
Date: Mon, 6 Jul 2026 19:37:14 +0530
Subject: [PATCH 1/4] [libcxx] enable AltiVec vectorization with element-wise
comparison wrapper
---
libcxx/include/__algorithm/find.h | 6 ++--
libcxx/include/__algorithm/mismatch.h | 6 ++--
libcxx/include/__algorithm/simd_utils.h | 34 +++++++++++++++++--
.../include/__cxx03/__algorithm/simd_utils.h | 3 +-
libcxx/include/__locale_dir/num.h | 2 +-
.../algorithms/vectorization.compile.pass.cpp | 3 --
6 files changed, 40 insertions(+), 14 deletions(-)
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index f677fb2c7392d..94087fb4afe78 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -81,7 +81,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last,
__lhs[__i] = std::__load_vector<__vec>(__first + __i * __vec_size);
for (size_t __i = 0; __i != __unroll_count; ++__i) {
- if (auto __cmp_res = __lhs[__i] == __values; std::__any_of(__cmp_res)) {
+ if (auto __cmp_res = std::__simd_compare_eq(__lhs[__i], __values); std::__any_of(__cmp_res)) {
auto __offset = __i * __vec_size + std::__find_first_set(__cmp_res);
return __first + __offset;
}
@@ -92,7 +92,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last,
// check the remaining 0-3 vectors
while (static_cast<size_t>(__last - __first) >= __vec_size) {
- if (auto __cmp_res = std::__load_vector<__vec>(__first) == __values; std::__any_of(__cmp_res)) {
+ if (auto __cmp_res = std::__simd_compare_eq(std::__load_vector<__vec>(__first), __values); std::__any_of(__cmp_res)) {
return __first + std::__find_first_set(__cmp_res);
}
__first += __vec_size;
@@ -105,7 +105,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last,
// (last - vector_size) to check the remaining elements
if (static_cast<size_t>(__first - __orig_first) >= __vec_size) {
__first = __last - __vec_size;
- return __first + std::__find_first_set(std::__load_vector<__vec>(__first) == __values);
+ return __first + std::__find_first_set(std::__simd_compare_eq(std::__load_vector<__vec>(__first), __values));
}
}
diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index 7111cd9398838..aba1e111ce470 100644
--- a/libcxx/include/__algorithm/mismatch.h
+++ b/libcxx/include/__algorithm/mismatch.h
@@ -78,7 +78,7 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
}
for (size_t __i = 0; __i != __unroll_count; ++__i) {
- if (auto __cmp_res = __lhs[__i] == __rhs[__i]; !std::__all_of(__cmp_res)) {
+ if (auto __cmp_res = std::__simd_compare_eq(__lhs[__i], __rhs[__i]); !std::__all_of(__cmp_res)) {
auto __offset = __i * __vec_size + std::__find_first_not_set(__cmp_res);
return {__first1 + __offset, __first2 + __offset};
}
@@ -90,7 +90,7 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
// check the remaining 0-3 vectors
while (static_cast<size_t>(__last1 - __first1) >= __vec_size) {
- if (auto __cmp_res = std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2);
+ if (auto __cmp_res = std::__simd_compare_eq(std::__load_vector<__vec>(__first1), std::__load_vector<__vec>(__first2));
!std::__all_of(__cmp_res)) {
auto __offset = std::__find_first_not_set(__cmp_res);
return {__first1 + __offset, __first2 + __offset};
@@ -108,7 +108,7 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
__first1 = __last1 - __vec_size;
__first2 = __last2 - __vec_size;
auto __offset =
- std::__find_first_not_set(std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2));
+ std::__find_first_not_set(std::__simd_compare_eq(std::__load_vector<__vec>(__first1), std::__load_vector<__vec>(__first2)));
return {__first1 + __offset, __first2 + __offset};
} // else loop over the elements individually
}
diff --git a/libcxx/include/__algorithm/simd_utils.h b/libcxx/include/__algorithm/simd_utils.h
index c47f79ac7f1dd..95da2066f44ae 100644
--- a/libcxx/include/__algorithm/simd_utils.h
+++ b/libcxx/include/__algorithm/simd_utils.h
@@ -25,8 +25,13 @@
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
-// TODO: Find out how altivec changes things and allow vectorizations there too.
-#if _LIBCPP_STD_VER >= 14 && defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(__ALTIVEC__)
+// AltiVec changes the semantics of vector comparisons: in `-faltivec-src-compat=xl`
+// mode, == on vector types yields a scalar bool rather than an element-wise mask,
+// which silently breaks the mask-based algorithms below. We enable vectorization on
+// AIX (where we can enforce the correct mode via a static_assert) but leave other
+// AltiVec platforms disabled until they are explicitly validated.
+#if _LIBCPP_STD_VER >= 14 && defined(_LIBCPP_COMPILER_CLANG_BASED) && \
+ (!defined(__ALTIVEC__) || defined(_AIX))
# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 1
#else
# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 0
@@ -76,7 +81,7 @@ using __get_as_integer_type_t _LIBCPP_NODEBUG = typename __get_as_integer_type_i
# if defined(__AVX__) || defined(__MVS__)
template <class _Tp>
inline constexpr size_t __native_vector_size = 32 / sizeof(_Tp);
-# elif defined(__SSE__) || defined(__ARM_NEON)
+# elif defined(__SSE__) || defined(__ARM_NEON) || defined(__ALTIVEC__)
template <class _Tp>
inline constexpr size_t __native_vector_size = 16 / sizeof(_Tp);
# elif defined(__MMX__)
@@ -126,6 +131,29 @@ template <class _VecT, size_t _Np, class _Iter>
}
_LIBCPP_DIAGNOSTIC_POP
+// On targets with Altivec (PowerPC), the == operator on __ext_vector_type__
+// vectors produces a deprecated vector bool result under the old XL compat mode.
+// Centralise the comparison here so the suppression is in one place.
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-altivec-src-compat")
+template <class _Tp, size_t _Np>
+[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI __simd_vector<_Tp, _Np>
+__simd_compare_eq(__simd_vector<_Tp, _Np> __lhs, __simd_vector<_Tp, _Np> __rhs) noexcept {
+ return __lhs == __rhs;
+}
+_LIBCPP_DIAGNOSTIC_POP
+
+# if defined(__ALTIVEC__)
+// In -faltivec-src-compat=xl mode, == on vector types returns a scalar bool,
+// which silently breaks the mask-based algorithms below. Refuse to compile in
+// that mode rather than produce wrong results.
+static_assert(sizeof(std::__simd_compare_eq(std::declval<__simd_vector<int, 4>>(),
+ std::declval<__simd_vector<int, 4>>())) ==
+ sizeof(__simd_vector<int, 4>),
+ "libc++'s vectorized algorithms require element-wise vector comparison semantics. "
+ "Compile with -faltivec-src-compat=mixed or -faltivec-src-compat=gcc (not =xl).");
+# endif
+
template <class _Tp, size_t _Np>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __any_of(__simd_vector<_Tp, _Np> __vec) noexcept {
return __builtin_reduce_or(__builtin_convertvector(__vec, __simd_vector<bool, _Np>));
diff --git a/libcxx/include/__cxx03/__algorithm/simd_utils.h b/libcxx/include/__cxx03/__algorithm/simd_utils.h
index 7b0e825afaa1f..d61a9f0524486 100644
--- a/libcxx/include/__cxx03/__algorithm/simd_utils.h
+++ b/libcxx/include/__cxx03/__algorithm/simd_utils.h
@@ -26,7 +26,8 @@
_LIBCPP_PUSH_MACROS
#include <__cxx03/__undef_macros>
-// TODO: Find out how altivec changes things and allow vectorizations there too.
+// The __cxx03 layer is a frozen C++03 ABI shim. Vectorization is handled by
+// the standard headers; do not enable it here.
#define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 0
#if _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS && !defined(__OPTIMIZE_SIZE__)
diff --git a/libcxx/include/__locale_dir/num.h b/libcxx/include/__locale_dir/num.h
index 5b3b917384121..792b24e72dd09 100644
--- a/libcxx/include/__locale_dir/num.h
+++ b/libcxx/include/__locale_dir/num.h
@@ -97,7 +97,7 @@ struct __num_get : protected __num_get_base {
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi")
using __vec = __simd_vector<char, 32>;
__vec __cmp = std::__partial_load<__vec, __int_chr_cnt>(__atoms);
- auto __res = __vec(__val) == __cmp;
+ auto __res = std::__simd_compare_eq(__vec(__val), __cmp);
if (std::__none_of(__res))
return __int_chr_cnt;
return std::min(__int_chr_cnt, std::__find_first_set(__res));
diff --git a/libcxx/test/libcxx/algorithms/vectorization.compile.pass.cpp b/libcxx/test/libcxx/algorithms/vectorization.compile.pass.cpp
index 109fc78507cc4..2b6a794652630 100644
--- a/libcxx/test/libcxx/algorithms/vectorization.compile.pass.cpp
+++ b/libcxx/test/libcxx/algorithms/vectorization.compile.pass.cpp
@@ -12,9 +12,6 @@
// We don't vectorize algorithms before C++14
// XFAIL: c++03, c++11
-// We don't vectorize algorithms on AIX right now.
-// XFAIL: target={{.+}}-aix{{.*}}
-
// This test ensures that we enable the vectorization of algorithms on the expected
// platforms.
>From 9380904348d900771216519ecf3e8e03b5450896 Mon Sep 17 00:00:00 2001
From: himadhith <himadhith.v at ibm.com>
Date: Tue, 7 Jul 2026 02:08:19 +0530
Subject: [PATCH 2/4] [libcxx] use decltype for __simd_compare_eq return type
on Altivec targets
---
libcxx/include/__algorithm/find.h | 3 ++-
libcxx/include/__algorithm/mismatch.h | 7 ++++---
libcxx/include/__algorithm/simd_utils.h | 13 +++++++------
3 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index 94087fb4afe78..c1c8f81bf3144 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -92,7 +92,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last,
// check the remaining 0-3 vectors
while (static_cast<size_t>(__last - __first) >= __vec_size) {
- if (auto __cmp_res = std::__simd_compare_eq(std::__load_vector<__vec>(__first), __values); std::__any_of(__cmp_res)) {
+ if (auto __cmp_res = std::__simd_compare_eq(std::__load_vector<__vec>(__first), __values);
+ std::__any_of(__cmp_res)) {
return __first + std::__find_first_set(__cmp_res);
}
__first += __vec_size;
diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index aba1e111ce470..f6e65822549b1 100644
--- a/libcxx/include/__algorithm/mismatch.h
+++ b/libcxx/include/__algorithm/mismatch.h
@@ -90,7 +90,8 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
// check the remaining 0-3 vectors
while (static_cast<size_t>(__last1 - __first1) >= __vec_size) {
- if (auto __cmp_res = std::__simd_compare_eq(std::__load_vector<__vec>(__first1), std::__load_vector<__vec>(__first2));
+ if (auto __cmp_res =
+ std::__simd_compare_eq(std::__load_vector<__vec>(__first1), std::__load_vector<__vec>(__first2));
!std::__all_of(__cmp_res)) {
auto __offset = std::__find_first_not_set(__cmp_res);
return {__first1 + __offset, __first2 + __offset};
@@ -107,8 +108,8 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
if (static_cast<size_t>(__first1 - __orig_first1) >= __vec_size) {
__first1 = __last1 - __vec_size;
__first2 = __last2 - __vec_size;
- auto __offset =
- std::__find_first_not_set(std::__simd_compare_eq(std::__load_vector<__vec>(__first1), std::__load_vector<__vec>(__first2)));
+ auto __offset = std::__find_first_not_set(
+ std::__simd_compare_eq(std::__load_vector<__vec>(__first1), std::__load_vector<__vec>(__first2)));
return {__first1 + __offset, __first2 + __offset};
} // else loop over the elements individually
}
diff --git a/libcxx/include/__algorithm/simd_utils.h b/libcxx/include/__algorithm/simd_utils.h
index 95da2066f44ae..44530d6cd8cae 100644
--- a/libcxx/include/__algorithm/simd_utils.h
+++ b/libcxx/include/__algorithm/simd_utils.h
@@ -30,8 +30,7 @@ _LIBCPP_PUSH_MACROS
// which silently breaks the mask-based algorithms below. We enable vectorization on
// AIX (where we can enforce the correct mode via a static_assert) but leave other
// AltiVec platforms disabled until they are explicitly validated.
-#if _LIBCPP_STD_VER >= 14 && defined(_LIBCPP_COMPILER_CLANG_BASED) && \
- (!defined(__ALTIVEC__) || defined(_AIX))
+#if _LIBCPP_STD_VER >= 14 && defined(_LIBCPP_COMPILER_CLANG_BASED) && (!defined(__ALTIVEC__) || defined(_AIX))
# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 1
#else
# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 0
@@ -134,11 +133,14 @@ _LIBCPP_DIAGNOSTIC_POP
// On targets with Altivec (PowerPC), the == operator on __ext_vector_type__
// vectors produces a deprecated vector bool result under the old XL compat mode.
// Centralise the comparison here so the suppression is in one place.
+// The return type is deduced via decltype because under Altivec the comparison
+// result element type differs from the operand element type (e.g. char16_t
+// operands yield a short mask vector).
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-altivec-src-compat")
template <class _Tp, size_t _Np>
-[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI __simd_vector<_Tp, _Np>
-__simd_compare_eq(__simd_vector<_Tp, _Np> __lhs, __simd_vector<_Tp, _Np> __rhs) noexcept {
+[[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI auto
+__simd_compare_eq(__simd_vector<_Tp, _Np> __lhs, __simd_vector<_Tp, _Np> __rhs) noexcept -> decltype(__lhs == __rhs) {
return __lhs == __rhs;
}
_LIBCPP_DIAGNOSTIC_POP
@@ -148,8 +150,7 @@ _LIBCPP_DIAGNOSTIC_POP
// which silently breaks the mask-based algorithms below. Refuse to compile in
// that mode rather than produce wrong results.
static_assert(sizeof(std::__simd_compare_eq(std::declval<__simd_vector<int, 4>>(),
- std::declval<__simd_vector<int, 4>>())) ==
- sizeof(__simd_vector<int, 4>),
+ std::declval<__simd_vector<int, 4>>())) == sizeof(__simd_vector<int, 4>),
"libc++'s vectorized algorithms require element-wise vector comparison semantics. "
"Compile with -faltivec-src-compat=mixed or -faltivec-src-compat=gcc (not =xl).");
# endif
>From ed766f8b8eb0f7c21e511fe77cec106a009ebb55 Mon Sep 17 00:00:00 2001
From: himadhith <himadhith.v at ibm.com>
Date: Tue, 7 Jul 2026 02:34:57 +0530
Subject: [PATCH 3/4] [libcxx][AIX] add -faltivec-src-compat=mixed to fix
vector comparisons
---
libcxx/CMakeLists.txt | 3 +++
libcxx/include/__algorithm/find.h | 2 +-
libcxx/include/__algorithm/mismatch.h | 2 +-
libcxx/include/__algorithm/simd_utils.h | 22 +++++++++-------------
libcxx/include/__locale_dir/num.h | 2 +-
5 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 31aaf2977a9af..4f86542020207 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -532,6 +532,9 @@ include(HandleLibcxxFlags)
if ("${CMAKE_SYSTEM_NAME}" MATCHES "AIX")
add_flags_if_supported("-mdefault-visibility-export-mapping=explicit")
+ # Required for __ext_vector_type__ comparisons to produce element-wise masks, not scalar bools (=xl default).
+ # Appended directly to LIBCXX_COMPILE_FLAGS so it applies only to the library sources, not the test suite.
+ list(APPEND LIBCXX_COMPILE_FLAGS "-faltivec-src-compat=mixed")
set(CMAKE_AIX_EXPORT_ALL_SYMBOLS OFF)
endif()
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index c1c8f81bf3144..343aec518f358 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -66,7 +66,7 @@ __find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
template <class _Tp, class _Up>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last, _Up __value) {
- if (!__libcpp_is_constant_evaluated()) {
+ if (!__libcpp_is_constant_evaluated() && std::__altivec_has_element_wise_compare) {
constexpr size_t __unroll_count = 4;
constexpr size_t __vec_size = __native_vector_size<_Tp>;
using __vec = __simd_vector<_Tp, __vec_size>;
diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index f6e65822549b1..ed9b8862953ba 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() && std::__altivec_has_element_wise_compare) {
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 44530d6cd8cae..040bdf9eb3c8c 100644
--- a/libcxx/include/__algorithm/simd_utils.h
+++ b/libcxx/include/__algorithm/simd_utils.h
@@ -130,12 +130,8 @@ template <class _VecT, size_t _Np, class _Iter>
}
_LIBCPP_DIAGNOSTIC_POP
-// On targets with Altivec (PowerPC), the == operator on __ext_vector_type__
-// vectors produces a deprecated vector bool result under the old XL compat mode.
-// Centralise the comparison here so the suppression is in one place.
-// The return type is deduced via decltype because under Altivec the comparison
-// result element type differs from the operand element type (e.g. char16_t
-// operands yield a short mask vector).
+// The return type uses decltype because under Altivec the comparison result
+// element type differs from the operand type (e.g. char16_t -> short mask).
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wdeprecated-altivec-src-compat")
template <class _Tp, size_t _Np>
@@ -145,14 +141,14 @@ __simd_compare_eq(__simd_vector<_Tp, _Np> __lhs, __simd_vector<_Tp, _Np> __rhs)
}
_LIBCPP_DIAGNOSTIC_POP
+// On non-Altivec targets this is always true. On Altivec targets it is false
+// when -faltivec-src-compat=xl is active (== returns scalar bool, not a mask).
# if defined(__ALTIVEC__)
-// In -faltivec-src-compat=xl mode, == on vector types returns a scalar bool,
-// which silently breaks the mask-based algorithms below. Refuse to compile in
-// that mode rather than produce wrong results.
-static_assert(sizeof(std::__simd_compare_eq(std::declval<__simd_vector<int, 4>>(),
- std::declval<__simd_vector<int, 4>>())) == sizeof(__simd_vector<int, 4>),
- "libc++'s vectorized algorithms require element-wise vector comparison semantics. "
- "Compile with -faltivec-src-compat=mixed or -faltivec-src-compat=gcc (not =xl).");
+inline constexpr bool __altivec_has_element_wise_compare =
+ sizeof(std::__simd_compare_eq(std::declval<__simd_vector<int, 4>>(),
+ std::declval<__simd_vector<int, 4>>())) == sizeof(__simd_vector<int, 4>);
+# else
+inline constexpr bool __altivec_has_element_wise_compare = true;
# endif
template <class _Tp, size_t _Np>
diff --git a/libcxx/include/__locale_dir/num.h b/libcxx/include/__locale_dir/num.h
index 792b24e72dd09..d1927be96f734 100644
--- a/libcxx/include/__locale_dir/num.h
+++ b/libcxx/include/__locale_dir/num.h
@@ -91,7 +91,7 @@ struct __num_get : protected __num_get_base {
_LIBCPP_HIDE_FROM_ABI static ptrdiff_t __atoms_offset(const _CharT* __atoms, _CharT __val) {
// TODO: Remove the manual vectorization once https://llvm.org/PR168551 is resolved
# if _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS
- if constexpr (is_same<_CharT, char>::value) {
+ if constexpr (is_same<_CharT, char>::value && std::__altivec_has_element_wise_compare) {
// TODO(LLVM 24): This can be removed, since -Wpsabi doesn't warn on [[gnu::always_inline]] functions anymore.
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi")
>From 2c04e251ed46c8044587ea6ef60586d3bd96baac Mon Sep 17 00:00:00 2001
From: himadhith <himadhith.v at ibm.com>
Date: Tue, 7 Jul 2026 10:48:04 +0530
Subject: [PATCH 4/4] [libcxx][AIX] use if constexpr to guard xl-mode vector
comparison paths
---
libcxx/include/__algorithm/find.h | 4 +++-
libcxx/include/__algorithm/mismatch.h | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index 343aec518f358..b3d3d8edf7410 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -66,7 +66,8 @@ __find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
template <class _Tp, class _Up>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last, _Up __value) {
- if (!__libcpp_is_constant_evaluated() && std::__altivec_has_element_wise_compare) {
+ if (!__libcpp_is_constant_evaluated()) {
+ if constexpr (std::__altivec_has_element_wise_compare) {
constexpr size_t __unroll_count = 4;
constexpr size_t __vec_size = __native_vector_size<_Tp>;
using __vec = __simd_vector<_Tp, __vec_size>;
@@ -108,6 +109,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find_vectorized(_Tp* __first, _Tp* __last,
__first = __last - __vec_size;
return __first + std::__find_first_set(std::__simd_compare_eq(std::__load_vector<__vec>(__first), __values));
}
+ } // end if constexpr
}
__identity __proj;
diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index ed9b8862953ba..c14f27650cf7a 100644
--- a/libcxx/include/__algorithm/mismatch.h
+++ b/libcxx/include/__algorithm/mismatch.h
@@ -65,7 +65,8 @@ __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() && std::__altivec_has_element_wise_compare) {
+ if (!__libcpp_is_constant_evaluated()) {
+ if constexpr (std::__altivec_has_element_wise_compare) {
auto __orig_first1 = __first1;
auto __last2 = __first2 + (__last1 - __first1);
while (static_cast<size_t>(__last1 - __first1) >= __unroll_count * __vec_size) [[__unlikely__]] {
@@ -112,6 +113,7 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
std::__simd_compare_eq(std::__load_vector<__vec>(__first1), std::__load_vector<__vec>(__first2)));
return {__first1 + __offset, __first2 + __offset};
} // else loop over the elements individually
+ } // end if constexpr
}
__equal_to __pred;
More information about the libcxx-commits
mailing list