Merge pull request #466 from clarfonthey/const-mask-splat

Make `Mask::splat` const
This commit is contained in:
Caleb Zulawski 2025-06-13 13:44:43 -04:00 committed by GitHub
commit 704a1a9064
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 29 additions and 15 deletions

View file

@ -18,7 +18,11 @@ impl<const N: usize> LaneCount<N> {
/// 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<const N: usize> Sealed for LaneCount<N> {}
@ -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
};
}
)+
};

View file

@ -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))
}

View file

@ -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 = <LaneCount<N> 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 {
<LaneCount<N> as SupportedLaneCount>::FULL_BIT_MASK
} else {
<LaneCount<N> 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 = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::EMPTY_BIT_MASK;
let len = bytes.as_mut().len();
bytes
.as_mut()

View file

@ -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 }))
}