-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[libc++] Start implementing std::datapar::simd #139919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
philnik777
wants to merge
1
commit into
llvm:main
Choose a base branch
from
philnik777:implement_simd
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
+3,261
−16
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesPatch is 117.36 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/139919.diff 52 Files Affected:
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 255a0474c0f6b..f6fcfa3fa8ed2 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -714,6 +714,10 @@ set(files
__ranges/view_interface.h
__ranges/views.h
__ranges/zip_view.h
+ __simd/abi.h
+ __simd/basic_simd.h
+ __simd/basic_simd_mask.h
+ __simd/simd_flags.h
__split_buffer
__std_mbstate_t.h
__stop_token/atomic_unique_lock.h
@@ -863,6 +867,7 @@ set(files
__type_traits/maybe_const.h
__type_traits/nat.h
__type_traits/negation.h
+ __type_traits/pack_utils.h
__type_traits/promote.h
__type_traits/rank.h
__type_traits/remove_all_extents.h
@@ -875,6 +880,7 @@ set(files
__type_traits/remove_reference.h
__type_traits/remove_volatile.h
__type_traits/result_of.h
+ __type_traits/standard_types.h
__type_traits/strip_signature.h
__type_traits/type_identity.h
__type_traits/type_list.h
@@ -1029,6 +1035,7 @@ set(files
semaphore
set
shared_mutex
+ simd
source_location
span
sstream
diff --git a/libcxx/include/__simd/abi.h b/libcxx/include/__simd/abi.h
new file mode 100644
index 0000000000000..7f54b02a05de8
--- /dev/null
+++ b/libcxx/include/__simd/abi.h
@@ -0,0 +1,165 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___SIMD_ABI_H
+#define _LIBCPP___SIMD_ABI_H
+
+#include <__concepts/convertible_to.h>
+#include <__concepts/equality_comparable.h>
+#include <__config>
+#include <__cstddef/size_t.h>
+#include <__type_traits/standard_types.h>
+#include <__utility/integer_sequence.h>
+#include <cstdint>
+
+#if _LIBCPP_STD_VER >= 26
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace datapar {
+
+template <class _Tp>
+inline constexpr bool __is_vectorizable_type_v = __is_standard_integer_type_v<_Tp> || __is_character_type_v<_Tp>;
+
+template <>
+inline constexpr bool __is_vectorizable_type_v<float> = true;
+
+template <>
+inline constexpr bool __is_vectorizable_type_v<double> = true;
+
+template <class _From, class _To>
+concept __value_preserving_convertible = requires(_From __from) { _To{__from}; };
+
+template <class _Tp>
+concept __constexpr_wrapper_like =
+ convertible_to<_Tp, decltype(_Tp::value)> && equality_comparable_with<_Tp, decltype(_Tp::value)> &&
+ bool_constant<_Tp() == _Tp::value>::value &&
+ bool_constant<static_cast<decltype(_Tp::value)>(_Tp()) == _Tp::value>::value;
+
+// [simd.expos]
+using __simd_size_type = int;
+
+template <class _Tp>
+struct __deduce_abi;
+
+template <class _Tp, __simd_size_type _Np>
+ requires __is_vectorizable_type_v<_Tp> && (_Np <= 64)
+using __deduce_abi_t = __deduce_abi<_Tp>::template __apply<_Np>;
+
+template <class _Tp>
+using __native_abi = __deduce_abi<_Tp>::template __apply<4>;
+
+template <class _Tp, class _Abi>
+inline constexpr __simd_size_type __simd_size_v = 0;
+
+template <size_t>
+struct __integer_from_impl;
+
+template <>
+struct __integer_from_impl<1> {
+ using type = uint8_t;
+};
+
+template <>
+struct __integer_from_impl<2> {
+ using type = uint16_t;
+};
+
+template <>
+struct __integer_from_impl<4> {
+ using type = uint32_t;
+};
+
+template <>
+struct __integer_from_impl<8> {
+ using type = uint64_t;
+};
+
+template <size_t _Bytes>
+using __integer_from = __integer_from_impl<_Bytes>::type;
+
+// ABI Types
+
+template <class _Tp, __simd_size_type _Np>
+struct __vector_size_abi {
+ using _SimdT [[__gnu__::__vector_size__(_Np * sizeof(_Tp))]] = _Tp;
+ using _MaskT [[__gnu__::__vector_size__(_Np * sizeof(_Tp))]] = __integer_from<sizeof(_Tp)>;
+
+ _LIBCPP_ALWAYS_INLINE constexpr _SimdT __select(_MaskT __mask, _SimdT __true, _SimdT __false) {
+ return __mask ? __true : __false;
+ }
+
+# ifdef _LIBCPP_COMPILER_CLANG_BASED
+ using _BoolVec __attribute__((__ext_vector_type__(_Np))) = bool;
+
+ static constexpr auto __int_size = _Np <= 8 ? 8 : _Np <= 16 ? 16 : _Np <= 32 ? 32 : 64;
+ static_assert(__int_size >= _Np);
+
+ using _IntSizeBoolVec __attribute__((__ext_vector_type__(__int_size))) = bool;
+
+ _LIBCPP_ALWAYS_INLINE static constexpr auto __mask_to_int(_BoolVec __mask) noexcept {
+ return [&]<size_t... _Origs, size_t... _Fillers>(index_sequence<_Origs...>, index_sequence<_Fillers...>)
+ _LIBCPP_ALWAYS_INLINE {
+ auto __vec = __builtin_convertvector(
+ __builtin_shufflevector(__mask, _BoolVec{}, _Origs..., ((void)_Fillers, _Np)...), _IntSizeBoolVec);
+ if constexpr (_Np <= 8)
+ return __builtin_bit_cast(unsigned char, __vec);
+ else if constexpr (_Np <= 16)
+ return __builtin_bit_cast(unsigned short, __vec);
+ else if constexpr (_Np <= 32)
+ return __builtin_bit_cast(unsigned int, __vec);
+ else
+ return __builtin_bit_cast(unsigned long long, __vec);
+ }(make_index_sequence<_Np>{}, make_index_sequence<__int_size - _Np>{});
+ }
+
+ _LIBCPP_ALWAYS_INLINE static constexpr bool __any_of(_MaskT __mask) noexcept {
+ return __builtin_reduce_or(__builtin_convertvector(__mask, _BoolVec));
+ }
+
+ _LIBCPP_ALWAYS_INLINE static constexpr bool __all_of(_MaskT __mask) noexcept {
+ return __builtin_reduce_and(__builtin_convertvector(__mask, _BoolVec));
+ }
+
+ _LIBCPP_ALWAYS_INLINE static constexpr __simd_size_type __reduce_count(_MaskT __mask) noexcept {
+ return __builtin_reduce_add(__builtin_convertvector(__builtin_convertvector(__mask, _BoolVec), _MaskT));
+ }
+
+ _LIBCPP_ALWAYS_INLINE static constexpr __simd_size_type __reduce_min_index(_MaskT __mask) noexcept {
+ return __builtin_ctzg(__mask_to_int(__builtin_convertvector(__mask, _BoolVec)));
+ }
+
+ _LIBCPP_ALWAYS_INLINE static constexpr __simd_size_type __reduce_max_index(_MaskT __mask) noexcept {
+ return __int_size - 1 - __builtin_clzg(__mask_to_int(__builtin_convertvector(__mask, _BoolVec)));
+ }
+# else
+ _LIBCPP_ALWAYS_INLINE constexpr bool __any_of(_MaskT __mask) noexcept {
+ for (size_t __i = 0; __i != _Np; ++__i) {
+ if (__mask[__i])
+ return true;
+ }
+ return false;
+ }
+# endif
+};
+
+template <class _Tp>
+ requires __is_vectorizable_type_v<_Tp>
+struct __deduce_abi<_Tp> {
+ template <__simd_size_type _Np>
+ using __apply = __vector_size_abi<_Tp, _Np>;
+};
+
+template <class _Tp, __simd_size_type _Np>
+inline constexpr __simd_size_type __simd_size_v<_Tp, __vector_size_abi<_Tp, _Np>> = _Np;
+
+} // namespace datapar
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 26
+
+#endif // _LIBCPP___SIMD_ABI_H
diff --git a/libcxx/include/__simd/basic_simd.h b/libcxx/include/__simd/basic_simd.h
new file mode 100644
index 0000000000000..acffa012d9ba1
--- /dev/null
+++ b/libcxx/include/__simd/basic_simd.h
@@ -0,0 +1,350 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___SIMD_BASIC_SIMD_H
+#define _LIBCPP___SIMD_BASIC_SIMD_H
+
+#include <__assert>
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__memory/assume_aligned.h>
+#include <__ranges/concepts.h>
+#include <__simd/abi.h>
+#include <__simd/basic_simd_mask.h>
+#include <__simd/simd_flags.h>
+#include <__type_traits/is_arithmetic.h>
+#include <__type_traits/pack_utils.h>
+#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/integer_sequence.h>
+
+#if _LIBCPP_STD_VER >= 26
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace datapar {
+
+_LIBCPP_DIAGNOSTIC_PUSH
+_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wpsabi")
+template <class _Tp, class _Abi = __native_abi<_Tp>>
+class basic_simd {
+public:
+ using value_type = _Tp;
+ using mask_type = basic_simd_mask<sizeof(_Tp), _Abi>;
+ using abi_type = _Abi;
+
+private:
+ using __data_t = abi_type::_SimdT;
+
+ __data_t __data_;
+
+ _LIBCPP_ALWAYS_INLINE static constexpr __data_t __broadcast(value_type __value) {
+ return [&]<size_t... _Indices>(index_sequence<_Indices...>) _LIBCPP_ALWAYS_INLINE noexcept {
+ return __data_t{((void)_Indices, __value)...};
+ }(make_index_sequence<size()>{});
+ }
+
+ template <class _Up>
+ _LIBCPP_ALWAYS_INLINE static constexpr __data_t __load_from_pointer(const _Up* __ptr) {
+ return [&]<size_t... _Indices>(index_sequence<_Indices...>) _LIBCPP_ALWAYS_INLINE noexcept {
+ return __data_t{__ptr[_Indices]...};
+ }(make_index_sequence<size()>{});
+ }
+
+public:
+ static constexpr integral_constant<__simd_size_type, __simd_size_v<value_type, abi_type>> size{};
+
+ constexpr basic_simd() noexcept = default;
+
+ // [simd.ctor]
+ template <convertible_to<value_type> _Up, class _From = remove_cvref_t<_Up>>
+ requires(__value_preserving_convertible<_From, value_type> ||
+ (!is_arithmetic_v<_From> && !__constexpr_wrapper_like<_From>) ||
+ (__constexpr_wrapper_like<_From> && is_arithmetic_v<remove_const_t<decltype(_From::value)>> &&
+ bool_constant<(static_cast<value_type>(_From::value) == _From::value)>::value))
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd(_Up&& __value) noexcept : __data_{__broadcast(__value)} {}
+
+ // TODO: converting constructor
+ // TODO: generator constructor
+ // TODO: flag constructor
+ // TODO: mask flag constructortrue
+
+ template <ranges::contiguous_range _Range, class... _Flags>
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd(_Range&& __range, simd_flags<_Flags...> = {}) noexcept
+ requires(ranges::size(__range) == size())
+ {
+ static_assert(__is_vectorizable_type_v<ranges::range_value_t<_Range>>, "Range has to be of a vectorizable type");
+ static_assert(__contains_type_v<__type_list<_Flags...>, __convert_flag> ||
+ __value_preserving_convertible<ranges::range_value_t<_Range>, value_type>,
+ "implicit conversion is not value preserving - consider using std::datapar::simd_flag_convert");
+ auto* __ptr = std::assume_aligned<__get_align_for<value_type, _Flags...>>(std::to_address(ranges::begin(__range)));
+ __data_ = __load_from_pointer(__ptr);
+ }
+
+ template <ranges::contiguous_range _Range, class... _Flags>
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd(
+ _Range&& __range, const mask_type& __mask, simd_flags<_Flags...> = {}) noexcept
+ requires(ranges::size(__range) == size())
+ {
+ static_assert(__is_vectorizable_type_v<ranges::range_value_t<_Range>>, "Range has to be of a vectorizable type");
+ static_assert(__contains_type_v<__type_list<_Flags...>, __convert_flag> ||
+ __value_preserving_convertible<ranges::range_value_t<_Range>, value_type>,
+ "implicit conversion is not value preserving - consider using std::datapar::simd_flag_convert");
+ auto* __ptr = std::assume_aligned<__get_align_for<value_type, _Flags...>>(std::to_address(ranges::begin(__range)));
+ __data_ = abi_type::__select(__mask.__data_, __load_from_pointer(__ptr), __broadcast(0));
+ }
+
+ // libc++ extensions
+ _LIBCPP_ALWAYS_INLINE constexpr explicit basic_simd(__data_t __data) noexcept : __data_(__data) {}
+
+ // [simd.subscr]
+ _LIBCPP_HIDE_FROM_ABI constexpr value_type operator[](__simd_size_type __index) const noexcept {
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__index >= 0 && __index < size(), "simd::operator[] out of bounds");
+ return __data_[__index];
+ }
+
+ // [simd.unary]
+
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd& operator++() noexcept
+ requires requires(value_type __v) { ++__v; }
+ {
+ __data_ += 1;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd operator++(int) noexcept
+ requires requires(value_type __v) { __v++; }
+ {
+ auto __ret = *this;
+ ++*this;
+ return __ret;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd& operator--() noexcept
+ requires requires(value_type __v) { --__v; }
+ {
+ __data_ -= 1;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd operator--(int) noexcept
+ requires requires(value_type __v) { __v--; }
+ {
+ auto __ret = *this;
+ --*this;
+ return __ret;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr mask_type operator!() const noexcept
+ requires requires(value_type __v) { !__v; }
+ {
+ return mask_type(!__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd operator~() const noexcept
+ requires requires(value_type __v) { ~__v; }
+ {
+ return basic_simd(~__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd operator+() const noexcept
+ requires requires(value_type __v) { +__v; }
+ {
+ return basic_simd(+__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI constexpr basic_simd operator-() const noexcept
+ requires requires(value_type __v) { -__v; }
+ {
+ return basic_simd(-__data_);
+ }
+
+ // [simd.binary]
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd operator+(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v + __v; }
+ {
+ return basic_simd(__lhs.__data_ + __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd operator-(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v - __v; }
+ {
+ return basic_simd(__lhs.__data_ - __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd operator*(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v * __v; }
+ {
+ return basic_simd(__lhs.__data_ * __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd operator/(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v / __v; }
+ {
+ return basic_simd(__lhs.__data_ / __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd operator%(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v % __v; }
+ {
+ return basic_simd(__lhs.__data_ % __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd operator&(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v & __v; }
+ {
+ return basic_simd(__lhs.__data_ & __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd operator|(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v | __v; }
+ {
+ return basic_simd(__lhs.__data_ | __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd operator^(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v ^ __v; }
+ {
+ return basic_simd(__lhs.__data_ ^ __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd
+ operator<<(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v << __v; }
+ {
+ return basic_simd(__lhs.__data_ << __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd
+ operator>>(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v << __v; }
+ {
+ return basic_simd(__lhs.__data_ >> __rhs.__data_);
+ }
+
+ // [simd.cassign]
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator+=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v += __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ + __rhs.__data_;
+ return __lhs;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator-=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v -= __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ - __rhs.__data_;
+ return __lhs;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator*=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v *= __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ * __rhs.__data_;
+ return __lhs;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator/=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v /= __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ / __rhs.__data_;
+ return __lhs;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator%=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v %= __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ % __rhs.__data_;
+ return __lhs;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator&=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v &= __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ & __rhs.__data_;
+ return __lhs;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator|=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v |= __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ | __rhs.__data_;
+ return __lhs;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator^=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v ^= __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ ^ __rhs.__data_;
+ return __lhs;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator<<=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v <<= __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ << __rhs.__data_;
+ return __lhs;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd& operator>>=(basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v >>= __v; }
+ {
+ __lhs.__data_ = __lhs.__data_ >> __rhs.__data_;
+ return __lhs;
+ }
+
+ // [simd.comparisons]
+ _LIBCPP_HIDE_FROM_ABI friend constexpr mask_type operator==(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v == __v; }
+ {
+ return mask_type(__lhs.__data_ == __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr mask_type operator!=(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v != __v; }
+ {
+ return mask_type(!(__lhs.__data_ == __rhs.__data_));
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr mask_type operator<(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v < __v; }
+ {
+ return mask_type(__lhs.__data_ < __rhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr mask_type operator>=(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v >= __v; }
+ {
+ return mask_type(__rhs.__data_ <= __lhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr mask_type operator>(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v > __v; }
+ {
+ return mask_type(__rhs.__data_ < __lhs.__data_);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr mask_type operator<=(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
+ requires requires(value_type __v) { __v <= __v; }
+ {
+ return mask_type(__lhs.__data_ <= __rhs.__data_);
+ }
+};
+_LIBCPP_DIAGNOSTIC_POP
+
+template <class _Tp, __simd_size_type _Np = __simd_size_v<_Tp, __native_abi<_Tp>>>
+using simd = basic_simd<_Tp, __deduce_abi_t<_Tp, _Np>>;
+
+} // namespace datapar
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 26
+
+#endif // _LIBCPP___SIMD_BASIC_SIMD_H
diff --git a/libcxx/include/__simd/basic_simd_mask.h b/libcxx/include/__simd/basic_simd_mask.h
new file mode 100644
index 0000000000000..b2f93d1c9705b
--- /dev/null
+++ b/libcxx/include/__simd/basic_simd_mask.h
@@ -0,0 +1,141 @@
+//===------...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions ,cpp,h -- libcxx/include/__simd/abi.h libcxx/include/__simd/basic_simd.h libcxx/include/__simd/basic_simd_mask.h libcxx/include/__simd/simd_flags.h libcxx/include/__type_traits/pack_utils.h libcxx/include/__type_traits/standard_types.h libcxx/include/simd libcxx/test/libcxx/numerics/simd/implementation_defined_conversions.pass.cpp libcxx/test/std/numerics/simd/simd.class/aliases.compile.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/add.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/bitand.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/bitor.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/bitshift_left.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/bitshift_right.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/divide.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/modulo.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/multiply.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/subtract.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.binary/xor.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/add.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/bitand.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/bitor.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/bitshift_left.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/bitshift_right.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/divide.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/modulo.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/multiply.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/subtract.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.cassign/xor.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.comparison/equality.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.comparison/ordering.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.ctor/broadcast.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.ctor/range.mask.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.ctor/range.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.unary/identity.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.unary/invert.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.unary/negation.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.unary/not.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.unary/postdec.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.unary/postinc.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.unary/predec.pass.cpp libcxx/test/std/numerics/simd/simd.class/simd.unary/preinc.pass.cpp libcxx/test/std/numerics/simd/simd.class/subscript.assert.pass.cpp libcxx/test/std/numerics/simd/simd.class/traits.compile.pass.cpp libcxx/test/std/numerics/simd/simd.flags.compile.pass.cpp libcxx/test/std/numerics/simd/simd.mask.class/simd.mask.ctor/broadcast.pass.cpp libcxx/test/std/numerics/simd/simd.mask.class/subscript.assert.pass.cpp libcxx/test/std/numerics/simd/simd.mask.class/traits.compile.pass.cpp libcxx/test/std/numerics/simd/simd.mask.reductions.pass.cpp libcxx/test/std/numerics/simd/utils.h libcxx/test/support/type_algorithms.h View the diff from clang-format here.diff --git a/libcxx/include/__simd/basic_simd.h b/libcxx/include/__simd/basic_simd.h
index acffa012d..d0897ad63 100644
--- a/libcxx/include/__simd/basic_simd.h
+++ b/libcxx/include/__simd/basic_simd.h
@@ -179,7 +179,7 @@ public:
}
_LIBCPP_HIDE_FROM_ABI friend constexpr basic_simd operator*(const basic_simd& __lhs, const basic_simd& __rhs) noexcept
- requires requires(value_type __v) { __v * __v; }
+ requires requires(value_type __v) { __v* __v; }
{
return basic_simd(__lhs.__data_ * __rhs.__data_);
}
diff --git a/libcxx/include/__type_traits/standard_types.h b/libcxx/include/__type_traits/standard_types.h
index f94599259..35d195b39 100644
--- a/libcxx/include/__type_traits/standard_types.h
+++ b/libcxx/include/__type_traits/standard_types.h
@@ -70,10 +70,10 @@ inline constexpr bool __is_character_type_v<char> = true;
template <>
inline constexpr bool __is_character_type_v<wchar_t> = true;
-#if _LIBCPP_HAS_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
template <>
inline constexpr bool __is_character_type_v<char8_t> = true;
-#endif
+# endif
template <>
inline constexpr bool __is_character_type_v<char16_t> = true;
diff --git a/libcxx/test/std/numerics/simd/simd.class/simd.binary/bitshift_left.pass.cpp b/libcxx/test/std/numerics/simd/simd.class/simd.binary/bitshift_left.pass.cpp
index 2236ebdcc..aaa4060e8 100644
--- a/libcxx/test/std/numerics/simd/simd.class/simd.binary/bitshift_left.pass.cpp
+++ b/libcxx/test/std/numerics/simd/simd.class/simd.binary/bitshift_left.pass.cpp
@@ -40,7 +40,9 @@ constexpr bool test() {
static_assert(has_bitshift_left<dp::simd<int>>);
types::for_each(types::vectorizable_float_types{}, []<class T> {
- simd_utils::test_sizes([]<int N>(std::integral_constant<int, N>) { static_assert(!has_bitshift_left<dp::simd<T, N>>); });
+ simd_utils::test_sizes([]<int N>(std::integral_constant<int, N>) {
+ static_assert(!has_bitshift_left<dp::simd<T, N>>);
+ });
});
return true;
diff --git a/libcxx/test/std/numerics/simd/simd.class/simd.cassign/bitshift_left.pass.cpp b/libcxx/test/std/numerics/simd/simd.class/simd.cassign/bitshift_left.pass.cpp
index b254a8d2f..0e588ce50 100644
--- a/libcxx/test/std/numerics/simd/simd.class/simd.cassign/bitshift_left.pass.cpp
+++ b/libcxx/test/std/numerics/simd/simd.class/simd.cassign/bitshift_left.pass.cpp
@@ -41,7 +41,9 @@ constexpr bool test() {
static_assert(has_bitshift_left<dp::simd<int>>);
types::for_each(types::vectorizable_float_types{}, []<class T> {
- simd_utils::test_sizes([]<int N>(std::integral_constant<int, N>) { static_assert(!has_bitshift_left<dp::simd<T, N>>); });
+ simd_utils::test_sizes([]<int N>(std::integral_constant<int, N>) {
+ static_assert(!has_bitshift_left<dp::simd<T, N>>);
+ });
});
return true;
diff --git a/libcxx/test/std/numerics/simd/simd.class/simd.comparison/ordering.pass.cpp b/libcxx/test/std/numerics/simd/simd.class/simd.comparison/ordering.pass.cpp
index 69b5bcd07..b19032068 100644
--- a/libcxx/test/std/numerics/simd/simd.class/simd.comparison/ordering.pass.cpp
+++ b/libcxx/test/std/numerics/simd/simd.class/simd.comparison/ordering.pass.cpp
@@ -58,8 +58,8 @@ constexpr bool test() {
});
types::for_each(types::vectorizable_float_types{}, []<class T> {
constexpr auto nan = std::numeric_limits<T>::quiet_NaN();
- dp::simd<T, 4> a = std::array<T, 4>{nan, nan, nan, nan};
- dp::simd<T, 4> b = a;
+ dp::simd<T, 4> a = std::array<T, 4>{nan, nan, nan, nan};
+ dp::simd<T, 4> b = a;
assert(dp::none_of(a < b));
assert(dp::none_of(a > b));
assert(dp::none_of(a <= b));
diff --git a/libcxx/test/std/numerics/simd/simd.flags.compile.pass.cpp b/libcxx/test/std/numerics/simd/simd.flags.compile.pass.cpp
index 097903cd4..97e533f68 100644
--- a/libcxx/test/std/numerics/simd/simd.flags.compile.pass.cpp
+++ b/libcxx/test/std/numerics/simd/simd.flags.compile.pass.cpp
@@ -48,5 +48,7 @@ static_assert(test<convert_flag_t>(dp::simd_flags<>{}, dp::simd_flags<convert_fl
static_assert(test<convert_flag_t>(dp::simd_flags<convert_flag_t>{}, dp::simd_flags<convert_flag_t>{}));
static_assert(test<overaligned_flag_t<1>>(dp::simd_flags<overaligned_flag_t<1>>{}, dp::simd_flags<>{}));
static_assert(test<overaligned_flag_t<1>>(dp::simd_flags<>{}, dp::simd_flags<overaligned_flag_t<1>>{}));
-static_assert(test<overaligned_flag_t<1>>(dp::simd_flags<overaligned_flag_t<1>>{}, dp::simd_flags<overaligned_flag_t<1>>{}));
-static_assert(test<overaligned_flag_t<16>>(dp::simd_flags<overaligned_flag_t<16>>{}, dp::simd_flags<overaligned_flag_t<1>>{}));
+static_assert(test<overaligned_flag_t<1>>(dp::simd_flags<overaligned_flag_t<1>>{},
+ dp::simd_flags<overaligned_flag_t<1>>{}));
+static_assert(test<overaligned_flag_t<16>>(dp::simd_flags<overaligned_flag_t<16>>{},
+ dp::simd_flags<overaligned_flag_t<1>>{}));
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This patch starts implementing P1928R15 and P3287R3.