about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Zulawski <caleb.zulawski@gmail.com>2024-02-17 12:04:52 -0500
committerGitHub <noreply@github.com>2024-02-17 12:04:52 -0500
commit7348d2da1bbacb7f64981e81992cc2a4833e83c3 (patch)
tree1fee65c9cdfd2836bc02e92594abfe9382915799
parent061d5acd93b93883f4e1bf680cb50a57141be07b (diff)
parentaebf6f156056ed803afed2ad055094d2ff4fc0cb (diff)
downloadrust-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.rs18
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