diff options
| author | Caleb Zulawski <caleb.zulawski@gmail.com> | 2024-02-17 12:04:52 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-17 12:04:52 -0500 |
| commit | 7348d2da1bbacb7f64981e81992cc2a4833e83c3 (patch) | |
| tree | 1fee65c9cdfd2836bc02e92594abfe9382915799 | |
| parent | 061d5acd93b93883f4e1bf680cb50a57141be07b (diff) | |
| parent | aebf6f156056ed803afed2ad055094d2ff4fc0cb (diff) | |
| download | rust-7348d2da1bbacb7f64981e81992cc2a4833e83c3.tar.gz rust-7348d2da1bbacb7f64981e81992cc2a4833e83c3.zip | |
Merge pull request #393 from rust-lang/assume-masks-are-correct
Assume masks are correct
| -rw-r--r-- | crates/core_simd/src/masks.rs | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index aad91d7acb7..e480c25a51e 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -12,7 +12,7 @@ )] mod mask_impl; -use crate::simd::{cmp::SimdPartialEq, LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount}; +use crate::simd::{LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount}; use core::cmp::Ordering; use core::{fmt, mem}; @@ -58,7 +58,16 @@ macro_rules! impl_element { where LaneCount<N>: SupportedLaneCount, { - (value.simd_eq(Simd::splat(0 as _)) | value.simd_eq(Simd::splat(-1 as _))).all() + // We can't use `Simd` directly, because `Simd`'s functions call this function and + // we will end up with an infinite loop. + // Safety: `value` is an integer vector + unsafe { + use core::intrinsics::simd; + let falses: Simd<Self, N> = simd::simd_eq(value, Simd::splat(0 as _)); + let trues: Simd<Self, N> = simd::simd_eq(value, Simd::splat(-1 as _)); + let valid: Simd<Self, N> = simd::simd_or(falses, trues); + simd::simd_reduce_all(valid) + } } #[inline] @@ -174,7 +183,10 @@ where #[must_use = "method returns a new mask and does not mutate the original value"] pub unsafe fn from_int_unchecked(value: Simd<T, N>) -> Self { // Safety: the caller must confirm this invariant - unsafe { Self(mask_impl::Mask::from_int_unchecked(value)) } + unsafe { + core::intrinsics::assume(<T as Sealed>::valid(value)); + Self(mask_impl::Mask::from_int_unchecked(value)) + } } /// Converts a vector of integers to a mask, where 0 represents `false` and -1 |
