Use u8xN for bitmasks

This commit is contained in:
Caleb Zulawski 2023-11-17 19:17:03 -05:00
parent 082e3c8a5d
commit 0ad68db91a
3 changed files with 14 additions and 56 deletions

View file

@ -286,7 +286,7 @@ where
/// The remaining bits are unset.
#[inline]
#[must_use = "method returns a new integer and does not mutate the original value"]
pub fn to_bitmask_vector(self) -> Simd<T, N> {
pub fn to_bitmask_vector(self) -> Simd<u8, N> {
self.0.to_bitmask_vector()
}
@ -295,7 +295,7 @@ where
/// For each bit, if it is set, the corresponding element in the mask is set to `true`.
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
pub fn from_bitmask_vector(bitmask: Simd<T, N>) -> Self {
pub fn from_bitmask_vector(bitmask: Simd<u8, N>) -> Self {
Self(mask_impl::Mask::from_bitmask_vector(bitmask))
}
}

View file

@ -121,45 +121,18 @@ where
#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"]
pub fn to_bitmask_vector(self) -> Simd<T, N> {
let mut bitmask = Self::splat(false).to_int();
assert!(
core::mem::size_of::<Simd<T, N>>()
>= core::mem::size_of::<<LaneCount<N> as SupportedLaneCount>::BitMask>()
);
// Safety: the bitmask vector is big enough to hold the bitmask
unsafe {
core::ptr::copy_nonoverlapping(
self.0.as_ref().as_ptr(),
bitmask.as_mut_array().as_mut_ptr() as _,
self.0.as_ref().len(),
);
}
pub fn to_bitmask_vector(self) -> Simd<u8, N> {
let mut bitmask = Simd::splat(0);
bitmask.as_mut_array()[..self.0.as_ref().len()].copy_from_slice(self.0.as_ref());
bitmask
}
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
pub fn from_bitmask_vector(bitmask: Simd<T, N>) -> Self {
pub fn from_bitmask_vector(bitmask: Simd<u8, N>) -> Self {
let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
assert!(
core::mem::size_of::<Simd<T, N>>()
>= core::mem::size_of::<<LaneCount<N> as SupportedLaneCount>::BitMask>()
);
// Safety: the bitmask vector is big enough to hold the bitmask
unsafe {
core::ptr::copy_nonoverlapping(
bitmask.as_array().as_ptr() as _,
bytes.as_mut().as_mut_ptr(),
bytes.as_ref().len(),
);
}
let len = bytes.as_ref().len();
bytes.as_mut().copy_from_slice(&bitmask.as_array()[..len]);
Self(bytes, PhantomData)
}

View file

@ -143,8 +143,8 @@ where
#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"]
pub fn to_bitmask_vector(self) -> Simd<T, N> {
let mut bitmask = Self::splat(false).to_int();
pub fn to_bitmask_vector(self) -> Simd<u8, N> {
let mut bitmask = Simd::splat(0);
// Safety: Bytes is the right size array
unsafe {
@ -159,15 +159,7 @@ where
}
}
assert!(
core::mem::size_of::<Simd<T, N>>()
>= core::mem::size_of::<<LaneCount<N> as SupportedLaneCount>::BitMask>()
);
core::ptr::copy_nonoverlapping(
bytes.as_ref().as_ptr(),
bitmask.as_mut_array().as_mut_ptr() as _,
bytes.as_ref().len(),
);
bitmask.as_mut_array()[..bytes.as_ref().len()].copy_from_slice(bytes.as_ref());
}
bitmask
@ -175,20 +167,13 @@ where
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
pub fn from_bitmask_vector(bitmask: Simd<T, N>) -> Self {
pub fn from_bitmask_vector(bitmask: Simd<u8, N>) -> Self {
let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
// Safety: Bytes is the right size array
unsafe {
assert!(
core::mem::size_of::<Simd<T, N>>()
>= core::mem::size_of::<<LaneCount<N> as SupportedLaneCount>::BitMask>()
);
core::ptr::copy_nonoverlapping(
bitmask.as_array().as_ptr() as _,
bytes.as_mut().as_mut_ptr(),
bytes.as_mut().len(),
);
let len = bytes.as_ref().len();
bytes.as_mut().copy_from_slice(&bitmask.as_array()[..len]);
// LLVM assumes bit order should match endianness
if cfg!(target_endian = "big") {