Skip to content

Commit 8554de3

Browse files
committed
[libc] Make simd helper functions static
Summary: It's important that these functions all be local to a TU as to not incur ABI restrictions. Otherwise, we end up with lots of warnings if we change or use different vector sizes.
1 parent 4294907 commit 8554de3

File tree

1 file changed

+46
-40
lines changed

1 file changed

+46
-40
lines changed

libc/src/__support/CPP/simd.h

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ using get_as_integer_type_t = unsigned _BitInt(sizeof(T) * CHAR_BIT);
3737

3838
#if defined(LIBC_TARGET_CPU_HAS_AVX512F)
3939
template <typename T>
40-
inline constexpr size_t native_vector_size = 64 / sizeof(T);
40+
LIBC_INLINE_VAR constexpr size_t native_vector_size = 64 / sizeof(T);
4141
#elif defined(LIBC_TARGET_CPU_HAS_AVX2)
4242
template <typename T>
43-
inline constexpr size_t native_vector_size = 32 / sizeof(T);
43+
LIBC_INLINE_VAR constexpr size_t native_vector_size = 32 / sizeof(T);
4444
#elif defined(LIBC_TARGET_CPU_HAS_SSE2) || defined(LIBC_TARGET_CPU_HAS_ARM_NEON)
4545
template <typename T>
46-
inline constexpr size_t native_vector_size = 16 / sizeof(T);
46+
LIBC_INLINE_VAR constexpr size_t native_vector_size = 16 / sizeof(T);
4747
#else
48-
template <typename T> inline constexpr size_t native_vector_size = 1;
48+
template <typename T> LIBC_INLINE constexpr size_t native_vector_size = 1;
4949
#endif
5050

5151
template <typename T> LIBC_INLINE constexpr T poison() {
@@ -90,122 +90,127 @@ using enable_if_simd_t = cpp::enable_if_t<is_simd_v<T>, T>;
9090

9191
// Casting.
9292
template <typename To, typename From, size_t N>
93-
LIBC_INLINE constexpr simd<To, N> simd_cast(simd<From, N> v) {
93+
LIBC_INLINE constexpr static simd<To, N> simd_cast(simd<From, N> v) {
9494
return __builtin_convertvector(v, simd<To, N>);
9595
}
9696

9797
// SIMD mask operations.
98-
template <size_t N> LIBC_INLINE constexpr bool all_of(simd<bool, N> m) {
98+
template <size_t N> LIBC_INLINE constexpr static bool all_of(simd<bool, N> m) {
9999
return __builtin_reduce_and(m);
100100
}
101-
template <size_t N> LIBC_INLINE constexpr bool any_of(simd<bool, N> m) {
101+
template <size_t N> LIBC_INLINE constexpr static bool any_of(simd<bool, N> m) {
102102
return __builtin_reduce_or(m);
103103
}
104-
template <size_t N> LIBC_INLINE constexpr bool none_of(simd<bool, N> m) {
104+
template <size_t N> LIBC_INLINE constexpr static bool none_of(simd<bool, N> m) {
105105
return !any_of(m);
106106
}
107-
template <size_t N> LIBC_INLINE constexpr bool some_of(simd<bool, N> m) {
107+
template <size_t N> LIBC_INLINE constexpr static bool some_of(simd<bool, N> m) {
108108
return any_of(m) && !all_of(m);
109109
}
110-
template <size_t N> LIBC_INLINE constexpr int popcount(simd<bool, N> m) {
110+
template <size_t N> LIBC_INLINE constexpr static int popcount(simd<bool, N> m) {
111111
return __builtin_popcountg(m);
112112
}
113-
template <size_t N> LIBC_INLINE constexpr int find_first_set(simd<bool, N> m) {
113+
template <size_t N>
114+
LIBC_INLINE constexpr static int find_first_set(simd<bool, N> m) {
114115
return __builtin_ctzg(m);
115116
}
116-
template <size_t N> LIBC_INLINE constexpr int find_last_set(simd<bool, N> m) {
117+
template <size_t N>
118+
LIBC_INLINE constexpr static int find_last_set(simd<bool, N> m) {
117119
constexpr size_t size = simd_size_v<simd<bool, N>>;
118120
return size - __builtin_clzg(m);
119121
}
120122

121123
// Elementwise operations.
122124
template <typename T, size_t N>
123-
LIBC_INLINE constexpr simd<T, N> min(simd<T, N> x, simd<T, N> y) {
125+
LIBC_INLINE constexpr static simd<T, N> min(simd<T, N> x, simd<T, N> y) {
124126
return __builtin_elementwise_min(x, y);
125127
}
126128
template <typename T, size_t N>
127-
LIBC_INLINE constexpr simd<T, N> max(simd<T, N> x, simd<T, N> y) {
129+
LIBC_INLINE constexpr static simd<T, N> max(simd<T, N> x, simd<T, N> y) {
128130
return __builtin_elementwise_max(x, y);
129131
}
130132

131133
template <typename T, size_t N>
132-
LIBC_INLINE constexpr simd<T, N> abs(simd<T, N> x) {
134+
LIBC_INLINE constexpr static simd<T, N> abs(simd<T, N> x) {
133135
return __builtin_elementwise_abs(x);
134136
}
135137
template <typename T, size_t N>
136-
LIBC_INLINE constexpr simd<T, N> fma(simd<T, N> x, simd<T, N> y, simd<T, N> z) {
138+
LIBC_INLINE constexpr static simd<T, N> fma(simd<T, N> x, simd<T, N> y,
139+
simd<T, N> z) {
137140
return __builtin_elementwise_fma(x, y, z);
138141
}
139142
template <typename T, size_t N>
140-
LIBC_INLINE constexpr simd<T, N> ceil(simd<T, N> x) {
143+
LIBC_INLINE constexpr static simd<T, N> ceil(simd<T, N> x) {
141144
return __builtin_elementwise_ceil(x);
142145
}
143146
template <typename T, size_t N>
144-
LIBC_INLINE constexpr simd<T, N> floor(simd<T, N> x) {
147+
LIBC_INLINE constexpr static simd<T, N> floor(simd<T, N> x) {
145148
return __builtin_elementwise_floor(x);
146149
}
147150
template <typename T, size_t N>
148-
LIBC_INLINE constexpr simd<T, N> roundeven(simd<T, N> x) {
151+
LIBC_INLINE constexpr static simd<T, N> roundeven(simd<T, N> x) {
149152
return __builtin_elementwise_roundeven(x);
150153
}
151154
template <typename T, size_t N>
152-
LIBC_INLINE constexpr simd<T, N> round(simd<T, N> x) {
155+
LIBC_INLINE constexpr static simd<T, N> round(simd<T, N> x) {
153156
return __builtin_elementwise_round(x);
154157
}
155158
template <typename T, size_t N>
156-
LIBC_INLINE constexpr simd<T, N> trunc(simd<T, N> x) {
159+
LIBC_INLINE constexpr static simd<T, N> trunc(simd<T, N> x) {
157160
return __builtin_elementwise_trunc(x);
158161
}
159162
template <typename T, size_t N>
160-
LIBC_INLINE constexpr simd<T, N> nearbyint(simd<T, N> x) {
163+
LIBC_INLINE constexpr static simd<T, N> nearbyint(simd<T, N> x) {
161164
return __builtin_elementwise_nearbyint(x);
162165
}
163166
template <typename T, size_t N>
164-
LIBC_INLINE constexpr simd<T, N> rint(simd<T, N> x) {
167+
LIBC_INLINE constexpr static simd<T, N> rint(simd<T, N> x) {
165168
return __builtin_elementwise_rint(x);
166169
}
167170
template <typename T, size_t N>
168-
LIBC_INLINE constexpr simd<T, N> canonicalize(simd<T, N> x) {
171+
LIBC_INLINE constexpr static simd<T, N> canonicalize(simd<T, N> x) {
169172
return __builtin_elementwise_canonicalize(x);
170173
}
171174
template <typename T, size_t N>
172-
LIBC_INLINE constexpr simd<T, N> copysign(simd<T, N> x, simd<T, N> y) {
175+
LIBC_INLINE constexpr static simd<T, N> copysign(simd<T, N> x, simd<T, N> y) {
173176
return __builtin_elementwise_copysign(x, y);
174177
}
175178
template <typename T, size_t N>
176-
LIBC_INLINE constexpr simd<T, N> fmod(simd<T, N> x, simd<T, N> y) {
179+
LIBC_INLINE constexpr static simd<T, N> fmod(simd<T, N> x, simd<T, N> y) {
177180
return __builtin_elementwise_fmod(x, y);
178181
}
179182

180183
// Reduction operations.
181184
template <typename T, size_t N, typename Op = cpp::plus<>>
182-
LIBC_INLINE constexpr T reduce(simd<T, N> v, Op op = {}) {
185+
LIBC_INLINE constexpr static T reduce(simd<T, N> v, Op op = {}) {
183186
return reduce(v, op);
184187
}
185188
template <typename T, size_t N>
186-
LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::plus<>) {
189+
LIBC_INLINE constexpr static T reduce(simd<T, N> v, cpp::plus<>) {
187190
return __builtin_reduce_add(v);
188191
}
189192
template <typename T, size_t N>
190-
LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::multiplies<>) {
193+
LIBC_INLINE constexpr static T reduce(simd<T, N> v, cpp::multiplies<>) {
191194
return __builtin_reduce_mul(v);
192195
}
193196
template <typename T, size_t N>
194-
LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::bit_and<>) {
197+
LIBC_INLINE constexpr static T reduce(simd<T, N> v, cpp::bit_and<>) {
195198
return __builtin_reduce_and(v);
196199
}
197200
template <typename T, size_t N>
198-
LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::bit_or<>) {
201+
LIBC_INLINE constexpr static T reduce(simd<T, N> v, cpp::bit_or<>) {
199202
return __builtin_reduce_or(v);
200203
}
201204
template <typename T, size_t N>
202-
LIBC_INLINE constexpr T reduce(simd<T, N> v, cpp::bit_xor<>) {
205+
LIBC_INLINE constexpr static T reduce(simd<T, N> v, cpp::bit_xor<>) {
203206
return __builtin_reduce_xor(v);
204207
}
205-
template <typename T, size_t N> LIBC_INLINE constexpr T hmin(simd<T, N> v) {
208+
template <typename T, size_t N>
209+
LIBC_INLINE constexpr static T hmin(simd<T, N> v) {
206210
return __builtin_reduce_min(v);
207211
}
208-
template <typename T, size_t N> LIBC_INLINE constexpr T hmax(simd<T, N> v) {
212+
template <typename T, size_t N>
213+
LIBC_INLINE constexpr static T hmax(simd<T, N> v) {
209214
return __builtin_reduce_max(v);
210215
}
211216

@@ -242,28 +247,29 @@ LIBC_INLINE enable_if_simd_t<T> masked_store(simd<bool, simd_size_v<T>> m, T v,
242247
}
243248

244249
// Construction helpers.
245-
template <typename T, size_t N> LIBC_INLINE constexpr simd<T, N> splat(T v) {
250+
template <typename T, size_t N>
251+
LIBC_INLINE constexpr static simd<T, N> splat(T v) {
246252
return simd<T, N>(v);
247253
}
248-
template <typename T> LIBC_INLINE constexpr simd<T> splat(T v) {
254+
template <typename T> LIBC_INLINE constexpr static simd<T> splat(T v) {
249255
return splat<T, simd_size_v<simd<T>>>(v);
250256
}
251257
template <typename T, unsigned N>
252-
LIBC_INLINE constexpr simd<T, N> iota(T base = T(0), T step = T(1)) {
258+
LIBC_INLINE constexpr static simd<T, N> iota(T base = T(0), T step = T(1)) {
253259
simd<T, N> v{};
254260
for (unsigned i = 0; i < N; ++i)
255261
v[i] = base + T(i) * step;
256262
return v;
257263
}
258264
template <typename T>
259-
LIBC_INLINE constexpr simd<T> iota(T base = T(0), T step = T(1)) {
265+
LIBC_INLINE constexpr static simd<T> iota(T base = T(0), T step = T(1)) {
260266
return iota<T, simd_size_v<simd<T>>>(base, step);
261267
}
262268

263269
// Conditional helpers.
264270
template <typename T, size_t N>
265-
LIBC_INLINE constexpr simd<T, N> select(simd<bool, N> m, simd<T, N> x,
266-
simd<T, N> y) {
271+
LIBC_INLINE constexpr static simd<T, N> select(simd<bool, N> m, simd<T, N> x,
272+
simd<T, N> y) {
267273
return m ? x : y;
268274
}
269275

0 commit comments

Comments
 (0)