diff --git a/crates/core_simd/src/lane_count.rs b/crates/core_simd/src/lane_count.rs index 280b27bc9bc6..c62b9d3b7d9b 100644 --- a/crates/core_simd/src/lane_count.rs +++ b/crates/core_simd/src/lane_count.rs @@ -18,7 +18,11 @@ impl LaneCount { /// Only SIMD vectors with supported lane counts are constructable. pub trait SupportedLaneCount: Sealed { #[doc(hidden)] - type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>; + type BitMask: Copy + AsRef<[u8]> + AsMut<[u8]>; + #[doc(hidden)] + const EMPTY_BIT_MASK: Self::BitMask; + #[doc(hidden)] + const FULL_BIT_MASK: Self::BitMask; } impl Sealed for LaneCount {} @@ -28,6 +32,15 @@ macro_rules! supported_lane_count { $( impl SupportedLaneCount for LaneCount<$lanes> { type BitMask = [u8; ($lanes + 7) / 8]; + const EMPTY_BIT_MASK: Self::BitMask = [0; ($lanes + 7) / 8]; + const FULL_BIT_MASK: Self::BitMask = { + const LEN: usize = ($lanes + 7) / 8; + let mut array = [!0u8; LEN]; + if $lanes % 8 > 0 { + array[LEN - 1] = (!0) >> (8 - $lanes % 8); + } + array + }; } )+ }; diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index 19d45f4d3b31..2b6be3676279 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -139,7 +139,8 @@ where { /// Constructs a mask by setting all elements to the given value. #[inline] - pub fn splat(value: bool) -> Self { + #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] + pub const fn splat(value: bool) -> Self { Self(mask_impl::Mask::splat(value)) } diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index 8221d8f17e90..ef03ec7f7159 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -78,17 +78,16 @@ where { #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) fn splat(value: bool) -> Self { - let mut mask = as SupportedLaneCount>::BitMask::default(); - if value { - mask.as_mut().fill(u8::MAX) - } else { - mask.as_mut().fill(u8::MIN) - } - if N % 8 > 0 { - *mask.as_mut().last_mut().unwrap() &= u8::MAX >> (8 - N % 8); - } - Self(mask, PhantomData) + #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] + pub(crate) const fn splat(value: bool) -> Self { + Self( + if value { + as SupportedLaneCount>::FULL_BIT_MASK + } else { + as SupportedLaneCount>::EMPTY_BIT_MASK + }, + PhantomData, + ) } #[inline] @@ -131,7 +130,7 @@ where #[inline] pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self { - let mut bytes = as SupportedLaneCount>::BitMask::default(); + let mut bytes = as SupportedLaneCount>::BitMask::EMPTY_BIT_MASK; let len = bytes.as_mut().len(); bytes .as_mut() diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index 4e98db4070a9..ddd7fb69b189 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -102,7 +102,8 @@ where { #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] - pub(crate) fn splat(value: bool) -> Self { + #[rustc_const_unstable(feature = "portable_simd", issue = "86656")] + pub(crate) const fn splat(value: bool) -> Self { Self(Simd::splat(if value { T::TRUE } else { T::FALSE })) }