Skip to content

Commit 257fa7a

Browse files
Drop splats for Simd<T, _>
Unfortunately, splatting impls currently break several crates. Rust needs more time to review possible mitigations, so drop the impls for the `impl Add<T> for Simd<T, _>` pattern, for now.
1 parent 6094f22 commit 257fa7a

File tree

5 files changed

+11
-197
lines changed

5 files changed

+11
-197
lines changed

crates/core_simd/examples/nbody.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ mod nbody {
9797
let sun = &mut sun[0];
9898
for body in rest {
9999
let m_ratio = body.mass / SOLAR_MASS;
100-
sun.v -= body.v * m_ratio;
100+
sun.v -= body.v * Simd::splat(m_ratio);
101101
}
102102
}
103103

@@ -143,14 +143,14 @@ mod nbody {
143143
let mut i = 0;
144144
for j in 0..N_BODIES {
145145
for k in j + 1..N_BODIES {
146-
let f = r[i] * mag[i];
147-
bodies[j].v -= f * bodies[k].mass;
148-
bodies[k].v += f * bodies[j].mass;
146+
let f = r[i] * Simd::splat(mag[i]);
147+
bodies[j].v -= f * Simd::splat(bodies[k].mass);
148+
bodies[k].v += f * Simd::splat(bodies[j].mass);
149149
i += 1
150150
}
151151
}
152152
for body in bodies {
153-
body.x += dt * body.v
153+
body.x += Simd::splat(dt) * body.v
154154
}
155155
}
156156

crates/core_simd/src/math.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ macro_rules! impl_uint_arith {
1717
/// let max = Simd::splat(MAX);
1818
/// let unsat = x + max;
1919
/// let sat = x.saturating_add(max);
20-
/// assert_eq!(x - 1, unsat);
20+
/// assert_eq!(unsat, Simd::from_array([1, 0, MAX, MAX - 1]));
2121
/// assert_eq!(sat, max);
2222
/// ```
2323
#[inline]
@@ -37,7 +37,7 @@ macro_rules! impl_uint_arith {
3737
/// let max = Simd::splat(MAX);
3838
/// let unsat = x - max;
3939
/// let sat = x.saturating_sub(max);
40-
/// assert_eq!(unsat, x + 1);
40+
/// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0]));
4141
/// assert_eq!(sat, Simd::splat(0));
4242
#[inline]
4343
pub fn saturating_sub(self, second: Self) -> Self {
@@ -105,7 +105,7 @@ macro_rules! impl_int_arith {
105105
#[inline]
106106
pub fn abs(self) -> Self {
107107
const SHR: $ty = <$ty>::BITS as $ty - 1;
108-
let m = self >> SHR;
108+
let m = self >> Simd::splat(SHR);
109109
(self^m) - m
110110
}
111111

@@ -128,7 +128,7 @@ macro_rules! impl_int_arith {
128128
pub fn saturating_abs(self) -> Self {
129129
// arith shift for -1 or 0 mask based on sign bit, giving 2s complement
130130
const SHR: $ty = <$ty>::BITS as $ty - 1;
131-
let m = self >> SHR;
131+
let m = self >> Simd::splat(SHR);
132132
(self^m).saturating_sub(m)
133133
}
134134

crates/core_simd/src/ops.rs

-138
Original file line numberDiff line numberDiff line change
@@ -118,34 +118,6 @@ macro_rules! impl_op {
118118
}
119119
}
120120
}
121-
122-
impl_ref_ops! {
123-
impl<const LANES: usize> core::ops::$trait<$scalar> for Simd<$scalar, LANES>
124-
where
125-
LaneCount<LANES>: SupportedLaneCount,
126-
{
127-
type Output = Self;
128-
129-
#[inline]
130-
fn $trait_fn(self, rhs: $scalar) -> Self::Output {
131-
core::ops::$trait::$trait_fn(self, Self::splat(rhs))
132-
}
133-
}
134-
}
135-
136-
impl_ref_ops! {
137-
impl<const LANES: usize> core::ops::$trait<Simd<$scalar, LANES>> for $scalar
138-
where
139-
LaneCount<LANES>: SupportedLaneCount,
140-
{
141-
type Output = Simd<$scalar, LANES>;
142-
143-
#[inline]
144-
fn $trait_fn(self, rhs: Simd<$scalar, LANES>) -> Self::Output {
145-
core::ops::$trait::$trait_fn(Simd::splat(self), rhs)
146-
}
147-
}
148-
}
149121
};
150122
}
151123

@@ -202,43 +174,6 @@ macro_rules! impl_unsigned_int_ops {
202174
}
203175
}
204176

205-
impl_ref_ops! {
206-
impl<const LANES: usize> core::ops::Div<$scalar> for Simd<$scalar, LANES>
207-
where
208-
LaneCount<LANES>: SupportedLaneCount,
209-
{
210-
type Output = Self;
211-
212-
#[inline]
213-
fn div(self, rhs: $scalar) -> Self::Output {
214-
if rhs == 0 {
215-
panic!("attempt to divide by zero");
216-
}
217-
if <$scalar>::MIN != 0 &&
218-
self.as_array().iter().any(|x| *x == <$scalar>::MIN) &&
219-
rhs == -1 as _ {
220-
panic!("attempt to divide with overflow");
221-
}
222-
let rhs = Self::splat(rhs);
223-
unsafe { intrinsics::simd_div(self, rhs) }
224-
}
225-
}
226-
}
227-
228-
impl_ref_ops! {
229-
impl<const LANES: usize> core::ops::Div<Simd<$scalar, LANES>> for $scalar
230-
where
231-
LaneCount<LANES>: SupportedLaneCount,
232-
{
233-
type Output = Simd<$scalar, LANES>;
234-
235-
#[inline]
236-
fn div(self, rhs: Simd<$scalar, LANES>) -> Self::Output {
237-
Simd::splat(self) / rhs
238-
}
239-
}
240-
}
241-
242177
// remainder panics on zero divisor
243178
impl_ref_ops! {
244179
impl<const LANES: usize> core::ops::Rem<Self> for Simd<$scalar, LANES>
@@ -268,43 +203,6 @@ macro_rules! impl_unsigned_int_ops {
268203
}
269204
}
270205

271-
impl_ref_ops! {
272-
impl<const LANES: usize> core::ops::Rem<$scalar> for Simd<$scalar, LANES>
273-
where
274-
LaneCount<LANES>: SupportedLaneCount,
275-
{
276-
type Output = Self;
277-
278-
#[inline]
279-
fn rem(self, rhs: $scalar) -> Self::Output {
280-
if rhs == 0 {
281-
panic!("attempt to calculate the remainder with a divisor of zero");
282-
}
283-
if <$scalar>::MIN != 0 &&
284-
self.as_array().iter().any(|x| *x == <$scalar>::MIN) &&
285-
rhs == -1 as _ {
286-
panic!("attempt to calculate the remainder with overflow");
287-
}
288-
let rhs = Self::splat(rhs);
289-
unsafe { intrinsics::simd_rem(self, rhs) }
290-
}
291-
}
292-
}
293-
294-
impl_ref_ops! {
295-
impl<const LANES: usize> core::ops::Rem<Simd<$scalar, LANES>> for $scalar
296-
where
297-
LaneCount<LANES>: SupportedLaneCount,
298-
{
299-
type Output = Simd<$scalar, LANES>;
300-
301-
#[inline]
302-
fn rem(self, rhs: Simd<$scalar, LANES>) -> Self::Output {
303-
Simd::splat(self) % rhs
304-
}
305-
}
306-
}
307-
308206
// shifts panic on overflow
309207
impl_ref_ops! {
310208
impl<const LANES: usize> core::ops::Shl<Self> for Simd<$scalar, LANES>
@@ -328,24 +226,6 @@ macro_rules! impl_unsigned_int_ops {
328226
}
329227
}
330228

331-
impl_ref_ops! {
332-
impl<const LANES: usize> core::ops::Shl<$scalar> for Simd<$scalar, LANES>
333-
where
334-
LaneCount<LANES>: SupportedLaneCount,
335-
{
336-
type Output = Self;
337-
338-
#[inline]
339-
fn shl(self, rhs: $scalar) -> Self::Output {
340-
if invalid_shift_rhs(rhs) {
341-
panic!("attempt to shift left with overflow");
342-
}
343-
let rhs = Self::splat(rhs);
344-
unsafe { intrinsics::simd_shl(self, rhs) }
345-
}
346-
}
347-
}
348-
349229
impl_ref_ops! {
350230
impl<const LANES: usize> core::ops::Shr<Self> for Simd<$scalar, LANES>
351231
where
@@ -367,24 +247,6 @@ macro_rules! impl_unsigned_int_ops {
367247
}
368248
}
369249
}
370-
371-
impl_ref_ops! {
372-
impl<const LANES: usize> core::ops::Shr<$scalar> for Simd<$scalar, LANES>
373-
where
374-
LaneCount<LANES>: SupportedLaneCount,
375-
{
376-
type Output = Self;
377-
378-
#[inline]
379-
fn shr(self, rhs: $scalar) -> Self::Output {
380-
if invalid_shift_rhs(rhs) {
381-
panic!("attempt to shift with overflow");
382-
}
383-
let rhs = Self::splat(rhs);
384-
unsafe { intrinsics::simd_shr(self, rhs) }
385-
}
386-
}
387-
}
388250
)*
389251
};
390252
}

crates/core_simd/src/vector/ptr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ where
2323
pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
2424
unsafe {
2525
let x: Simd<usize, LANES> = mem::transmute_copy(&self);
26-
mem::transmute_copy(&{ x + (addend * mem::size_of::<T>()) })
26+
mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
2727
}
2828
}
2929
}
@@ -49,7 +49,7 @@ where
4949
pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
5050
unsafe {
5151
let x: Simd<usize, LANES> = mem::transmute_copy(&self);
52-
mem::transmute_copy(&{ x + (addend * mem::size_of::<T>()) })
52+
mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
5353
}
5454
}
5555
}

crates/core_simd/tests/ops_macros.rs

-48
Original file line numberDiff line numberDiff line change
@@ -38,37 +38,13 @@ macro_rules! impl_binary_op_test {
3838
);
3939
}
4040

41-
fn scalar_rhs<const LANES: usize>() {
42-
test_helpers::test_binary_scalar_rhs_elementwise(
43-
&<Simd<$scalar, LANES> as core::ops::$trait<$scalar>>::$fn,
44-
&$scalar_fn,
45-
&|_, _| true,
46-
);
47-
}
48-
49-
fn scalar_lhs<const LANES: usize>() {
50-
test_helpers::test_binary_scalar_lhs_elementwise(
51-
&<$scalar as core::ops::$trait<Simd<$scalar, LANES>>>::$fn,
52-
&$scalar_fn,
53-
&|_, _| true,
54-
);
55-
}
56-
5741
fn assign<const LANES: usize>() {
5842
test_helpers::test_binary_elementwise(
5943
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign>::$fn_assign(&mut a, b); a },
6044
&$scalar_fn,
6145
&|_, _| true,
6246
);
6347
}
64-
65-
fn assign_scalar_rhs<const LANES: usize>() {
66-
test_helpers::test_binary_scalar_rhs_elementwise(
67-
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a },
68-
&$scalar_fn,
69-
&|_, _| true,
70-
);
71-
}
7248
}
7349
}
7450
};
@@ -99,37 +75,13 @@ macro_rules! impl_binary_checked_op_test {
9975
);
10076
}
10177

102-
fn scalar_rhs<const LANES: usize>() {
103-
test_helpers::test_binary_scalar_rhs_elementwise(
104-
&<Simd<$scalar, LANES> as core::ops::$trait<$scalar>>::$fn,
105-
&$scalar_fn,
106-
&|x, y| x.iter().all(|x| $check_fn(*x, y)),
107-
);
108-
}
109-
110-
fn scalar_lhs<const LANES: usize>() {
111-
test_helpers::test_binary_scalar_lhs_elementwise(
112-
&<$scalar as core::ops::$trait<Simd<$scalar, LANES>>>::$fn,
113-
&$scalar_fn,
114-
&|x, y| y.iter().all(|y| $check_fn(x, *y)),
115-
);
116-
}
117-
11878
fn assign<const LANES: usize>() {
11979
test_helpers::test_binary_elementwise(
12080
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign>::$fn_assign(&mut a, b); a },
12181
&$scalar_fn,
12282
&|x, y| x.iter().zip(y.iter()).all(|(x, y)| $check_fn(*x, *y)),
12383
)
12484
}
125-
126-
fn assign_scalar_rhs<const LANES: usize>() {
127-
test_helpers::test_binary_scalar_rhs_elementwise(
128-
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a },
129-
&$scalar_fn,
130-
&|x, y| x.iter().all(|x| $check_fn(*x, y)),
131-
)
132-
}
13385
}
13486
}
13587
};

0 commit comments

Comments
 (0)