|
1 | 1 | use crate::simd::{ |
2 | | - LaneCount, Mask, Select, Simd, SupportedLaneCount, |
| 2 | + LaneCount, Mask, Select, Simd, SimdElement, SupportedLaneCount, |
3 | 3 | cmp::SimdPartialEq, |
4 | 4 | ptr::{SimdConstPtr, SimdMutPtr}, |
5 | 5 | }; |
@@ -152,94 +152,108 @@ macro_rules! impl_float { |
152 | 152 |
|
153 | 153 | impl_float! { f32, f64 } |
154 | 154 |
|
155 | | -macro_rules! impl_mask { |
156 | | - { $($integer:ty),* } => { |
157 | | - $( |
158 | | - impl<const N: usize> SimdPartialOrd for Mask<$integer, N> |
159 | | - where |
160 | | - LaneCount<N>: SupportedLaneCount, |
161 | | - { |
162 | | - #[inline] |
163 | | - fn simd_lt(self, other: Self) -> Self::Mask { |
164 | | - // Safety: `self` is a vector, and the result of the comparison |
165 | | - // is always a valid mask. |
166 | | - unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_lt(self.to_simd(), other.to_simd())) } |
167 | | - } |
| 155 | +impl<T, const N: usize> SimdPartialOrd for Mask<T, N> |
| 156 | +where |
| 157 | + T: SimdElement, |
| 158 | + LaneCount<N>: SupportedLaneCount, |
| 159 | +{ |
| 160 | + #[inline] |
| 161 | + fn simd_lt(self, other: Self) -> Self::Mask { |
| 162 | + // Use intrinsic to avoid extra bounds on T. |
| 163 | + // Safety: `self` is a vector, and the result of the comparison is always a valid mask. |
| 164 | + unsafe { |
| 165 | + Self::from_simd_unchecked(core::intrinsics::simd::simd_lt( |
| 166 | + self.to_simd(), |
| 167 | + other.to_simd(), |
| 168 | + )) |
| 169 | + } |
| 170 | + } |
168 | 171 |
|
169 | | - #[inline] |
170 | | - fn simd_le(self, other: Self) -> Self::Mask { |
171 | | - // Safety: `self` is a vector, and the result of the comparison |
172 | | - // is always a valid mask. |
173 | | - unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_le(self.to_simd(), other.to_simd())) } |
174 | | - } |
| 172 | + #[inline] |
| 173 | + fn simd_le(self, other: Self) -> Self::Mask { |
| 174 | + // Use intrinsic to avoid extra bounds on T. |
| 175 | + // Safety: `self` is a vector, and the result of the comparison is always a valid mask. |
| 176 | + unsafe { |
| 177 | + Self::from_simd_unchecked(core::intrinsics::simd::simd_le( |
| 178 | + self.to_simd(), |
| 179 | + other.to_simd(), |
| 180 | + )) |
| 181 | + } |
| 182 | + } |
175 | 183 |
|
176 | | - #[inline] |
177 | | - fn simd_gt(self, other: Self) -> Self::Mask { |
178 | | - // Safety: `self` is a vector, and the result of the comparison |
179 | | - // is always a valid mask. |
180 | | - unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_gt(self.to_simd(), other.to_simd())) } |
181 | | - } |
| 184 | + #[inline] |
| 185 | + fn simd_gt(self, other: Self) -> Self::Mask { |
| 186 | + // Use intrinsic to avoid extra bounds on T. |
| 187 | + // Safety: `self` is a vector, and the result of the comparison is always a valid mask. |
| 188 | + unsafe { |
| 189 | + Self::from_simd_unchecked(core::intrinsics::simd::simd_gt( |
| 190 | + self.to_simd(), |
| 191 | + other.to_simd(), |
| 192 | + )) |
| 193 | + } |
| 194 | + } |
182 | 195 |
|
183 | | - #[inline] |
184 | | - fn simd_ge(self, other: Self) -> Self::Mask { |
185 | | - // Safety: `self` is a vector, and the result of the comparison |
186 | | - // is always a valid mask. |
187 | | - unsafe { Self::from_simd_unchecked(core::intrinsics::simd::simd_ge(self.to_simd(), other.to_simd())) } |
188 | | - } |
| 196 | + #[inline] |
| 197 | + fn simd_ge(self, other: Self) -> Self::Mask { |
| 198 | + // Use intrinsic to avoid extra bounds on T. |
| 199 | + // Safety: `self` is a vector, and the result of the comparison is always a valid mask. |
| 200 | + unsafe { |
| 201 | + Self::from_simd_unchecked(core::intrinsics::simd::simd_ge( |
| 202 | + self.to_simd(), |
| 203 | + other.to_simd(), |
| 204 | + )) |
189 | 205 | } |
| 206 | + } |
| 207 | +} |
190 | 208 |
|
191 | | - impl<const N: usize> SimdOrd for Mask<$integer, N> |
192 | | - where |
193 | | - LaneCount<N>: SupportedLaneCount, |
194 | | - { |
195 | | - #[inline] |
196 | | - fn simd_max(self, other: Self) -> Self { |
197 | | - self.simd_gt(other).select(other, self) |
198 | | - } |
| 209 | +impl<T, const N: usize> SimdOrd for Mask<T, N> |
| 210 | +where |
| 211 | + T: SimdElement, |
| 212 | + LaneCount<N>: SupportedLaneCount, |
| 213 | +{ |
| 214 | + #[inline] |
| 215 | + fn simd_max(self, other: Self) -> Self { |
| 216 | + self.simd_gt(other).select(other, self) |
| 217 | + } |
199 | 218 |
|
200 | | - #[inline] |
201 | | - fn simd_min(self, other: Self) -> Self { |
202 | | - self.simd_lt(other).select(other, self) |
203 | | - } |
| 219 | + #[inline] |
| 220 | + fn simd_min(self, other: Self) -> Self { |
| 221 | + self.simd_lt(other).select(other, self) |
| 222 | + } |
204 | 223 |
|
205 | | - #[inline] |
206 | | - #[track_caller] |
207 | | - fn simd_clamp(self, min: Self, max: Self) -> Self { |
208 | | - assert!( |
209 | | - min.simd_le(max).all(), |
210 | | - "each element in `min` must be less than or equal to the corresponding element in `max`", |
211 | | - ); |
212 | | - self.simd_max(min).simd_min(max) |
213 | | - } |
214 | | - } |
215 | | - )* |
| 224 | + #[inline] |
| 225 | + #[track_caller] |
| 226 | + fn simd_clamp(self, min: Self, max: Self) -> Self { |
| 227 | + assert!( |
| 228 | + min.simd_le(max).all(), |
| 229 | + "each element in `min` must be less than or equal to the corresponding element in `max`", |
| 230 | + ); |
| 231 | + self.simd_max(min).simd_min(max) |
216 | 232 | } |
217 | 233 | } |
218 | 234 |
|
219 | | -impl_mask! { i8, i16, i32, i64, isize } |
220 | | - |
221 | 235 | impl<T, const N: usize> SimdPartialOrd for Simd<*const T, N> |
222 | 236 | where |
223 | 237 | LaneCount<N>: SupportedLaneCount, |
224 | 238 | { |
225 | 239 | #[inline] |
226 | 240 | fn simd_lt(self, other: Self) -> Self::Mask { |
227 | | - self.addr().simd_lt(other.addr()) |
| 241 | + self.addr().simd_lt(other.addr()).cast::<*const T>() |
228 | 242 | } |
229 | 243 |
|
230 | 244 | #[inline] |
231 | 245 | fn simd_le(self, other: Self) -> Self::Mask { |
232 | | - self.addr().simd_le(other.addr()) |
| 246 | + self.addr().simd_le(other.addr()).cast::<*const T>() |
233 | 247 | } |
234 | 248 |
|
235 | 249 | #[inline] |
236 | 250 | fn simd_gt(self, other: Self) -> Self::Mask { |
237 | | - self.addr().simd_gt(other.addr()) |
| 251 | + self.addr().simd_gt(other.addr()).cast::<*const T>() |
238 | 252 | } |
239 | 253 |
|
240 | 254 | #[inline] |
241 | 255 | fn simd_ge(self, other: Self) -> Self::Mask { |
242 | | - self.addr().simd_ge(other.addr()) |
| 256 | + self.addr().simd_ge(other.addr()).cast::<*const T>() |
243 | 257 | } |
244 | 258 | } |
245 | 259 |
|
@@ -274,22 +288,22 @@ where |
274 | 288 | { |
275 | 289 | #[inline] |
276 | 290 | fn simd_lt(self, other: Self) -> Self::Mask { |
277 | | - self.addr().simd_lt(other.addr()) |
| 291 | + self.addr().simd_lt(other.addr()).cast::<*mut T>() |
278 | 292 | } |
279 | 293 |
|
280 | 294 | #[inline] |
281 | 295 | fn simd_le(self, other: Self) -> Self::Mask { |
282 | | - self.addr().simd_le(other.addr()) |
| 296 | + self.addr().simd_le(other.addr()).cast::<*mut T>() |
283 | 297 | } |
284 | 298 |
|
285 | 299 | #[inline] |
286 | 300 | fn simd_gt(self, other: Self) -> Self::Mask { |
287 | | - self.addr().simd_gt(other.addr()) |
| 301 | + self.addr().simd_gt(other.addr()).cast::<*mut T>() |
288 | 302 | } |
289 | 303 |
|
290 | 304 | #[inline] |
291 | 305 | fn simd_ge(self, other: Self) -> Self::Mask { |
292 | | - self.addr().simd_ge(other.addr()) |
| 306 | + self.addr().simd_ge(other.addr()).cast::<*mut T>() |
293 | 307 | } |
294 | 308 | } |
295 | 309 |
|
|
0 commit comments