Skip to content

Commit 704a1a9

Browse files
Merge pull request #466 from clarfonthey/const-mask-splat
Make `Mask::splat` const
2 parents 7a0cc2f + a857909 commit 704a1a9

File tree

4 files changed

+29
-15
lines changed

4 files changed

+29
-15
lines changed

crates/core_simd/src/lane_count.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ impl<const N: usize> LaneCount<N> {
1818
/// Only SIMD vectors with supported lane counts are constructable.
1919
pub trait SupportedLaneCount: Sealed {
2020
#[doc(hidden)]
21-
type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>;
21+
type BitMask: Copy + AsRef<[u8]> + AsMut<[u8]>;
22+
#[doc(hidden)]
23+
const EMPTY_BIT_MASK: Self::BitMask;
24+
#[doc(hidden)]
25+
const FULL_BIT_MASK: Self::BitMask;
2226
}
2327

2428
impl<const N: usize> Sealed for LaneCount<N> {}
@@ -28,6 +32,15 @@ macro_rules! supported_lane_count {
2832
$(
2933
impl SupportedLaneCount for LaneCount<$lanes> {
3034
type BitMask = [u8; ($lanes + 7) / 8];
35+
const EMPTY_BIT_MASK: Self::BitMask = [0; ($lanes + 7) / 8];
36+
const FULL_BIT_MASK: Self::BitMask = {
37+
const LEN: usize = ($lanes + 7) / 8;
38+
let mut array = [!0u8; LEN];
39+
if $lanes % 8 > 0 {
40+
array[LEN - 1] = (!0) >> (8 - $lanes % 8);
41+
}
42+
array
43+
};
3144
}
3245
)+
3346
};

crates/core_simd/src/masks.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ where
139139
{
140140
/// Constructs a mask by setting all elements to the given value.
141141
#[inline]
142-
pub fn splat(value: bool) -> Self {
142+
#[rustc_const_unstable(feature = "portable_simd", issue = "86656")]
143+
pub const fn splat(value: bool) -> Self {
143144
Self(mask_impl::Mask::splat(value))
144145
}
145146

crates/core_simd/src/masks/bitmask.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,16 @@ where
7878
{
7979
#[inline]
8080
#[must_use = "method returns a new mask and does not mutate the original value"]
81-
pub(crate) fn splat(value: bool) -> Self {
82-
let mut mask = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
83-
if value {
84-
mask.as_mut().fill(u8::MAX)
85-
} else {
86-
mask.as_mut().fill(u8::MIN)
87-
}
88-
if N % 8 > 0 {
89-
*mask.as_mut().last_mut().unwrap() &= u8::MAX >> (8 - N % 8);
90-
}
91-
Self(mask, PhantomData)
81+
#[rustc_const_unstable(feature = "portable_simd", issue = "86656")]
82+
pub(crate) const fn splat(value: bool) -> Self {
83+
Self(
84+
if value {
85+
<LaneCount<N> as SupportedLaneCount>::FULL_BIT_MASK
86+
} else {
87+
<LaneCount<N> as SupportedLaneCount>::EMPTY_BIT_MASK
88+
},
89+
PhantomData,
90+
)
9291
}
9392

9493
#[inline]
@@ -131,7 +130,7 @@ where
131130

132131
#[inline]
133132
pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self {
134-
let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
133+
let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::EMPTY_BIT_MASK;
135134
let len = bytes.as_mut().len();
136135
bytes
137136
.as_mut()

crates/core_simd/src/masks/full_masks.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ where
102102
{
103103
#[inline]
104104
#[must_use = "method returns a new mask and does not mutate the original value"]
105-
pub(crate) fn splat(value: bool) -> Self {
105+
#[rustc_const_unstable(feature = "portable_simd", issue = "86656")]
106+
pub(crate) const fn splat(value: bool) -> Self {
106107
Self(Simd::splat(if value { T::TRUE } else { T::FALSE }))
107108
}
108109

0 commit comments

Comments
 (0)