Skip to content

Commit ce92300

Browse files
Merge pull request #117 from rust-lang/feature/mask-select
Implement select on masks
2 parents dfebaf9 + 45d7e80 commit ce92300

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

crates/core_simd/src/intrinsics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ extern "platform-intrinsic" {
8282

8383
// select
8484
pub(crate) fn simd_select<T, U>(m: T, a: U, b: U) -> U;
85+
#[allow(unused)]
8586
pub(crate) fn simd_select_bitmask<T, U>(m: T, a: U, b: U) -> U;
8687
}
8788

crates/core_simd/src/select.rs

+41-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
mod sealed {
2-
pub trait Sealed {}
2+
pub trait Sealed {}
33
}
44
use sealed::Sealed;
55

66
/// Supporting trait for vector `select` function
7-
pub trait Select<Mask>: Sealed {}
7+
pub trait Select<Mask>: Sealed {
8+
#[doc(hidden)]
9+
fn select(mask: Mask, true_values: Self, false_values: Self) -> Self;
10+
}
811

912
macro_rules! impl_select {
1013
{
@@ -17,9 +20,32 @@ macro_rules! impl_select {
1720
crate::$mask<LANES>: crate::Mask,
1821
crate::$bits_ty<LANES>: crate::LanesAtMost32,
1922
Self: crate::LanesAtMost32,
20-
{}
23+
{
24+
#[doc(hidden)]
25+
#[inline]
26+
fn select(mask: crate::$mask<LANES>, true_values: Self, false_values: Self) -> Self {
27+
unsafe { crate::intrinsics::simd_select(mask.to_int(), true_values, false_values) }
28+
}
29+
}
2130
)*
2231

32+
impl<const LANES: usize> Sealed for crate::$mask<LANES>
33+
where
34+
Self: crate::Mask,
35+
crate::$bits_ty<LANES>: crate::LanesAtMost32,
36+
{}
37+
impl<const LANES: usize> Select<Self> for crate::$mask<LANES>
38+
where
39+
Self: crate::Mask,
40+
crate::$bits_ty<LANES>: crate::LanesAtMost32,
41+
{
42+
#[doc(hidden)]
43+
#[inline]
44+
fn select(mask: Self, true_values: Self, false_values: Self) -> Self {
45+
mask & true_values | !mask & false_values
46+
}
47+
}
48+
2349
impl<const LANES: usize> crate::$mask<LANES>
2450
where
2551
Self: crate::Mask,
@@ -38,8 +64,19 @@ macro_rules! impl_select {
3864
/// let c = mask.select(a, b);
3965
/// assert_eq!(c.to_array(), [0, 5, 6, 3]);
4066
/// ```
67+
///
68+
/// `select` can also be used on masks:
69+
/// ```
70+
/// # use core_simd::Mask32;
71+
/// let a = Mask32::from_array([true, true, false, false]);
72+
/// let b = Mask32::from_array([false, false, true, true]);
73+
/// let mask = Mask32::from_array([true, false, false, true]);
74+
/// let c = mask.select(a, b);
75+
/// assert_eq!(c.to_array(), [true, false, true, false]);
76+
/// ```
77+
#[inline]
4178
pub fn select<S: Select<Self>>(self, true_values: S, false_values: S) -> S {
42-
unsafe { crate::intrinsics::simd_select(self.to_int(), true_values, false_values) }
79+
S::select(self, true_values, false_values)
4380
}
4481
}
4582
}

crates/core_simd/tests/mask_ops_impl/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#[macro_use]
22
mod mask_macros;
33

4+
#[rustfmt::skip]
45
mod mask8;
56
mod mask16;
67
mod mask32;

0 commit comments

Comments
 (0)