@@ -32,21 +32,8 @@ static_assert(LIBC_HAS_VECTOR_TYPE, "compiler does not support vector types");
32
32
33
33
namespace internal {
34
34
35
- template <size_t Size> struct get_as_integer_type ;
36
- template <> struct get_as_integer_type <1 > {
37
- using type = uint8_t ;
38
- };
39
- template <> struct get_as_integer_type <2 > {
40
- using type = uint16_t ;
41
- };
42
- template <> struct get_as_integer_type <4 > {
43
- using type = uint32_t ;
44
- };
45
- template <> struct get_as_integer_type <8 > {
46
- using type = uint64_t ;
47
- };
48
- template <class T >
49
- using get_as_integer_type_t = typename get_as_integer_type<sizeof (T)>::type;
35
+ template <typename T>
36
+ using get_as_integer_type_t = unsigned _BitInt (sizeof (T) * CHAR_BIT);
50
37
51
38
#if defined(LIBC_TARGET_CPU_HAS_AVX512F)
52
39
template <typename T>
@@ -60,6 +47,10 @@ inline constexpr size_t native_vector_size = 16 / sizeof(T);
60
47
#else
61
48
template <typename T> inline constexpr size_t native_vector_size = 1 ;
62
49
#endif
50
+
51
+ template <typename T> LIBC_INLINE constexpr T poison () {
52
+ return __builtin_nondeterministic_value (T ());
53
+ }
63
54
} // namespace internal
64
55
65
56
// Type aliases.
@@ -71,9 +62,9 @@ template <typename T>
71
62
using simd_mask = simd<bool , internal::native_vector_size<T>>;
72
63
73
64
// Type trait helpers.
74
- template <typename T> struct simd_size : cpp::integral_constant< size_t , 1 > {};
75
- template < typename T, unsigned N>
76
- struct simd_size <simd<T, N>> : cpp::integral_constant< size_t , N> { };
65
+ template <typename T>
66
+ struct simd_size : cpp::integral_constant< size_t , __builtin_vectorelements(T)> {
67
+ };
77
68
template <class T > constexpr size_t simd_size_v = simd_size<T>::value;
78
69
79
70
template <typename T> struct is_simd : cpp::integral_constant<bool , false > {};
@@ -87,6 +78,13 @@ template <unsigned N>
87
78
struct is_simd_mask <simd<bool , N>> : cpp::integral_constant<bool , true > {};
88
79
template <class T > constexpr bool is_simd_mask_v = is_simd_mask<T>::value;
89
80
81
+ template <typename T> struct simd_element_type ;
82
+ template <typename T, size_t N> struct simd_element_type <simd<T, N>> {
83
+ using type = T;
84
+ };
85
+ template <typename T>
86
+ using simd_element_type_t = typename simd_element_type<T>::type;
87
+
90
88
template <typename T>
91
89
using enable_if_simd_t = cpp::enable_if_t <is_simd_v<T>, T>;
92
90
@@ -182,10 +180,10 @@ LIBC_INLINE enable_if_simd_t<T> store_aligned(T v, void *ptr) {
182
180
store_unaligned<T>(v, __builtin_assume_aligned (ptr, alignof (T)));
183
181
}
184
182
template <typename T>
185
- LIBC_INLINE enable_if_simd_t <T> masked_load (simd< bool , simd_size_v<T>> m,
186
- void *ptr) {
187
- return __builtin_masked_load (
188
- m, static_cast <T *>( __builtin_assume_aligned ( ptr, alignof (T))) );
183
+ LIBC_INLINE enable_if_simd_t <T>
184
+ masked_load (simd< bool , simd_size_v<T>> m, void *ptr,
185
+ T passthru = internal::poison<simd_element_type<T>>()) {
186
+ return __builtin_masked_load ( m, ptr, passthru );
189
187
}
190
188
template <typename T>
191
189
LIBC_INLINE enable_if_simd_t <T> masked_store (simd<bool , simd_size_v<T>> m, T v,
0 commit comments