Skip to content

Commit 86b9f69

Browse files
#260: Add .min and .max for integers
1 parent 89bc660 commit 86b9f69

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

crates/core_simd/src/comparisons.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,37 @@ where
6666
unsafe { Mask::from_int_unchecked(intrinsics::simd_ge(self, other)) }
6767
}
6868
}
69+
70+
macro_rules! impl_min_max_vector {
71+
{ $type:ty } => {
72+
impl<const LANES: usize> Simd<$type, LANES>
73+
where
74+
LaneCount<LANES>: SupportedLaneCount,
75+
{
76+
/// Returns the lane-wise minimum with other
77+
#[must_use = "method returns a new vector and does not mutate the original value"]
78+
#[inline]
79+
pub fn min(self, other: Self) -> Self {
80+
self.lanes_gt(other).select(other, self)
81+
}
82+
83+
/// Returns the lane-wise maximum with other
84+
#[must_use = "method returns a new vector and does not mutate the original value"]
85+
#[inline]
86+
pub fn max(self, other: Self) -> Self {
87+
self.lanes_lt(other).select(other, self)
88+
}
89+
}
90+
}
91+
}
92+
93+
impl_min_max_vector!(i8);
94+
impl_min_max_vector!(i16);
95+
impl_min_max_vector!(i32);
96+
impl_min_max_vector!(i64);
97+
impl_min_max_vector!(isize);
98+
impl_min_max_vector!(u8);
99+
impl_min_max_vector!(u16);
100+
impl_min_max_vector!(u32);
101+
impl_min_max_vector!(u64);
102+
impl_min_max_vector!(usize);

crates/core_simd/tests/i16_ops.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
#![feature(portable_simd)]
2+
use core_simd::i16x2;
23

34
#[macro_use]
45
mod ops_macros;
56
impl_signed_tests! { i16 }
7+
8+
#[test]
9+
fn max_is_not_lexicographic() {
10+
let a = i16x2::splat(10);
11+
let b = i16x2::from_array([-4, 12]);
12+
assert_eq!(a.max(b), i16x2::from_array([10, 12]));
13+
}
14+
15+
#[test]
16+
fn min_is_not_lexicographic() {
17+
let a = i16x2::splat(10);
18+
let b = i16x2::from_array([12, -4]);
19+
assert_eq!(a.min(b), i16x2::from_array([10, -4]));
20+
}

crates/core_simd/tests/ops_macros.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,23 @@ macro_rules! impl_signed_tests {
222222
assert_eq!(a % b, Vector::<LANES>::splat(0));
223223
}
224224

225+
fn min<const LANES: usize>() {
226+
let a = Vector::<LANES>::splat(Scalar::MIN);
227+
let b = Vector::<LANES>::splat(0);
228+
assert_eq!(a.min(b), a);
229+
let a = Vector::<LANES>::splat(Scalar::MAX);
230+
let b = Vector::<LANES>::splat(0);
231+
assert_eq!(a.min(b), b);
232+
}
233+
234+
fn max<const LANES: usize>() {
235+
let a = Vector::<LANES>::splat(Scalar::MIN);
236+
let b = Vector::<LANES>::splat(0);
237+
assert_eq!(a.max(b), b);
238+
let a = Vector::<LANES>::splat(Scalar::MAX);
239+
let b = Vector::<LANES>::splat(0);
240+
assert_eq!(a.max(b), a);
241+
}
225242
}
226243

227244
test_helpers::test_lanes_panic! {

0 commit comments

Comments
 (0)