Skip to content

Commit 490b5cf

Browse files
Merge pull request #360 from rust-lang/shift-scalar
Add scalar shifts
2 parents 7c7dbe0 + e51ee24 commit 490b5cf

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

crates/core_simd/src/ops.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use core::ops::{Shl, Shr};
66

77
mod assign;
88
mod deref;
9+
mod shift_scalar;
910
mod unary;
1011

1112
impl<I, T, const LANES: usize> core::ops::Index<I> for Simd<T, LANES>
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Shift operations uniquely typically only have a scalar on the right-hand side.
2+
// Here, we implement shifts for scalar RHS arguments.
3+
4+
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
5+
6+
macro_rules! impl_splatted_shifts {
7+
{ impl $trait:ident :: $trait_fn:ident for $ty:ty } => {
8+
impl<const N: usize> core::ops::$trait<$ty> for Simd<$ty, N>
9+
where
10+
LaneCount<N>: SupportedLaneCount,
11+
{
12+
type Output = Self;
13+
fn $trait_fn(self, rhs: $ty) -> Self::Output {
14+
self.$trait_fn(Simd::splat(rhs))
15+
}
16+
}
17+
18+
impl<const N: usize> core::ops::$trait<&$ty> for Simd<$ty, N>
19+
where
20+
LaneCount<N>: SupportedLaneCount,
21+
{
22+
type Output = Self;
23+
fn $trait_fn(self, rhs: &$ty) -> Self::Output {
24+
self.$trait_fn(Simd::splat(*rhs))
25+
}
26+
}
27+
28+
impl<'lhs, const N: usize> core::ops::$trait<$ty> for &'lhs Simd<$ty, N>
29+
where
30+
LaneCount<N>: SupportedLaneCount,
31+
{
32+
type Output = Simd<$ty, N>;
33+
fn $trait_fn(self, rhs: $ty) -> Self::Output {
34+
self.$trait_fn(Simd::splat(rhs))
35+
}
36+
}
37+
38+
impl<'lhs, const N: usize> core::ops::$trait<&$ty> for &'lhs Simd<$ty, N>
39+
where
40+
LaneCount<N>: SupportedLaneCount,
41+
{
42+
type Output = Simd<$ty, N>;
43+
fn $trait_fn(self, rhs: &$ty) -> Self::Output {
44+
self.$trait_fn(Simd::splat(*rhs))
45+
}
46+
}
47+
};
48+
{ $($ty:ty),* } => {
49+
$(
50+
impl_splatted_shifts! { impl Shl::shl for $ty }
51+
impl_splatted_shifts! { impl Shr::shr for $ty }
52+
)*
53+
}
54+
}
55+
56+
// In the past there were inference issues when generically splatting arguments.
57+
// Enumerate them instead.
58+
impl_splatted_shifts! { i8, i16, i32, i64, isize, u8, u16, u32, u64, usize }

crates/core_simd/tests/ops_macros.rs

+30
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,36 @@ macro_rules! impl_binary_checked_op_test {
9494
macro_rules! impl_common_integer_tests {
9595
{ $vector:ident, $scalar:ident } => {
9696
test_helpers::test_lanes! {
97+
fn shr<const LANES: usize>() {
98+
use core::ops::Shr;
99+
let shr = |x: $scalar, y: $scalar| x.wrapping_shr(y as _);
100+
test_helpers::test_binary_elementwise(
101+
&<$vector::<LANES> as Shr<$vector::<LANES>>>::shr,
102+
&shr,
103+
&|_, _| true,
104+
);
105+
test_helpers::test_binary_scalar_rhs_elementwise(
106+
&<$vector::<LANES> as Shr<$scalar>>::shr,
107+
&shr,
108+
&|_, _| true,
109+
);
110+
}
111+
112+
fn shl<const LANES: usize>() {
113+
use core::ops::Shl;
114+
let shl = |x: $scalar, y: $scalar| x.wrapping_shl(y as _);
115+
test_helpers::test_binary_elementwise(
116+
&<$vector::<LANES> as Shl<$vector::<LANES>>>::shl,
117+
&shl,
118+
&|_, _| true,
119+
);
120+
test_helpers::test_binary_scalar_rhs_elementwise(
121+
&<$vector::<LANES> as Shl<$scalar>>::shl,
122+
&shl,
123+
&|_, _| true,
124+
);
125+
}
126+
97127
fn reduce_sum<const LANES: usize>() {
98128
test_helpers::test_1(&|x| {
99129
test_helpers::prop_assert_biteq! (

0 commit comments

Comments
 (0)