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.
This commit is contained in:
parent
6094f22ceb
commit
257fa7aa6d
@ -97,7 +97,7 @@ mod nbody {
|
||||
let sun = &mut sun[0];
|
||||
for body in rest {
|
||||
let m_ratio = body.mass / SOLAR_MASS;
|
||||
sun.v -= body.v * m_ratio;
|
||||
sun.v -= body.v * Simd::splat(m_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,14 +143,14 @@ mod nbody {
|
||||
let mut i = 0;
|
||||
for j in 0..N_BODIES {
|
||||
for k in j + 1..N_BODIES {
|
||||
let f = r[i] * mag[i];
|
||||
bodies[j].v -= f * bodies[k].mass;
|
||||
bodies[k].v += f * bodies[j].mass;
|
||||
let f = r[i] * Simd::splat(mag[i]);
|
||||
bodies[j].v -= f * Simd::splat(bodies[k].mass);
|
||||
bodies[k].v += f * Simd::splat(bodies[j].mass);
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
for body in bodies {
|
||||
body.x += dt * body.v
|
||||
body.x += Simd::splat(dt) * body.v
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ macro_rules! impl_uint_arith {
|
||||
/// let max = Simd::splat(MAX);
|
||||
/// let unsat = x + max;
|
||||
/// let sat = x.saturating_add(max);
|
||||
/// assert_eq!(x - 1, unsat);
|
||||
/// assert_eq!(unsat, Simd::from_array([1, 0, MAX, MAX - 1]));
|
||||
/// assert_eq!(sat, max);
|
||||
/// ```
|
||||
#[inline]
|
||||
@ -37,7 +37,7 @@ macro_rules! impl_uint_arith {
|
||||
/// let max = Simd::splat(MAX);
|
||||
/// let unsat = x - max;
|
||||
/// let sat = x.saturating_sub(max);
|
||||
/// assert_eq!(unsat, x + 1);
|
||||
/// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0]));
|
||||
/// assert_eq!(sat, Simd::splat(0));
|
||||
#[inline]
|
||||
pub fn saturating_sub(self, second: Self) -> Self {
|
||||
@ -105,7 +105,7 @@ macro_rules! impl_int_arith {
|
||||
#[inline]
|
||||
pub fn abs(self) -> Self {
|
||||
const SHR: $ty = <$ty>::BITS as $ty - 1;
|
||||
let m = self >> SHR;
|
||||
let m = self >> Simd::splat(SHR);
|
||||
(self^m) - m
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ macro_rules! impl_int_arith {
|
||||
pub fn saturating_abs(self) -> Self {
|
||||
// arith shift for -1 or 0 mask based on sign bit, giving 2s complement
|
||||
const SHR: $ty = <$ty>::BITS as $ty - 1;
|
||||
let m = self >> SHR;
|
||||
let m = self >> Simd::splat(SHR);
|
||||
(self^m).saturating_sub(m)
|
||||
}
|
||||
|
||||
|
@ -118,34 +118,6 @@ macro_rules! impl_op {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::$trait<$scalar> for Simd<$scalar, LANES>
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn $trait_fn(self, rhs: $scalar) -> Self::Output {
|
||||
core::ops::$trait::$trait_fn(self, Self::splat(rhs))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::$trait<Simd<$scalar, LANES>> for $scalar
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
type Output = Simd<$scalar, LANES>;
|
||||
|
||||
#[inline]
|
||||
fn $trait_fn(self, rhs: Simd<$scalar, LANES>) -> Self::Output {
|
||||
core::ops::$trait::$trait_fn(Simd::splat(self), rhs)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -202,43 +174,6 @@ macro_rules! impl_unsigned_int_ops {
|
||||
}
|
||||
}
|
||||
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::Div<$scalar> for Simd<$scalar, LANES>
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn div(self, rhs: $scalar) -> Self::Output {
|
||||
if rhs == 0 {
|
||||
panic!("attempt to divide by zero");
|
||||
}
|
||||
if <$scalar>::MIN != 0 &&
|
||||
self.as_array().iter().any(|x| *x == <$scalar>::MIN) &&
|
||||
rhs == -1 as _ {
|
||||
panic!("attempt to divide with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { intrinsics::simd_div(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::Div<Simd<$scalar, LANES>> for $scalar
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
type Output = Simd<$scalar, LANES>;
|
||||
|
||||
#[inline]
|
||||
fn div(self, rhs: Simd<$scalar, LANES>) -> Self::Output {
|
||||
Simd::splat(self) / rhs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remainder panics on zero divisor
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::Rem<Self> for Simd<$scalar, LANES>
|
||||
@ -268,43 +203,6 @@ macro_rules! impl_unsigned_int_ops {
|
||||
}
|
||||
}
|
||||
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::Rem<$scalar> for Simd<$scalar, LANES>
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn rem(self, rhs: $scalar) -> Self::Output {
|
||||
if rhs == 0 {
|
||||
panic!("attempt to calculate the remainder with a divisor of zero");
|
||||
}
|
||||
if <$scalar>::MIN != 0 &&
|
||||
self.as_array().iter().any(|x| *x == <$scalar>::MIN) &&
|
||||
rhs == -1 as _ {
|
||||
panic!("attempt to calculate the remainder with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { intrinsics::simd_rem(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::Rem<Simd<$scalar, LANES>> for $scalar
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
type Output = Simd<$scalar, LANES>;
|
||||
|
||||
#[inline]
|
||||
fn rem(self, rhs: Simd<$scalar, LANES>) -> Self::Output {
|
||||
Simd::splat(self) % rhs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shifts panic on overflow
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::Shl<Self> for Simd<$scalar, LANES>
|
||||
@ -328,24 +226,6 @@ macro_rules! impl_unsigned_int_ops {
|
||||
}
|
||||
}
|
||||
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::Shl<$scalar> for Simd<$scalar, LANES>
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn shl(self, rhs: $scalar) -> Self::Output {
|
||||
if invalid_shift_rhs(rhs) {
|
||||
panic!("attempt to shift left with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { intrinsics::simd_shl(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::Shr<Self> for Simd<$scalar, LANES>
|
||||
where
|
||||
@ -367,24 +247,6 @@ macro_rules! impl_unsigned_int_ops {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_ref_ops! {
|
||||
impl<const LANES: usize> core::ops::Shr<$scalar> for Simd<$scalar, LANES>
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
type Output = Self;
|
||||
|
||||
#[inline]
|
||||
fn shr(self, rhs: $scalar) -> Self::Output {
|
||||
if invalid_shift_rhs(rhs) {
|
||||
panic!("attempt to shift with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { intrinsics::simd_shr(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ where
|
||||
pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
|
||||
unsafe {
|
||||
let x: Simd<usize, LANES> = mem::transmute_copy(&self);
|
||||
mem::transmute_copy(&{ x + (addend * mem::size_of::<T>()) })
|
||||
mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,7 +49,7 @@ where
|
||||
pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
|
||||
unsafe {
|
||||
let x: Simd<usize, LANES> = mem::transmute_copy(&self);
|
||||
mem::transmute_copy(&{ x + (addend * mem::size_of::<T>()) })
|
||||
mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,22 +38,6 @@ macro_rules! impl_binary_op_test {
|
||||
);
|
||||
}
|
||||
|
||||
fn scalar_rhs<const LANES: usize>() {
|
||||
test_helpers::test_binary_scalar_rhs_elementwise(
|
||||
&<Simd<$scalar, LANES> as core::ops::$trait<$scalar>>::$fn,
|
||||
&$scalar_fn,
|
||||
&|_, _| true,
|
||||
);
|
||||
}
|
||||
|
||||
fn scalar_lhs<const LANES: usize>() {
|
||||
test_helpers::test_binary_scalar_lhs_elementwise(
|
||||
&<$scalar as core::ops::$trait<Simd<$scalar, LANES>>>::$fn,
|
||||
&$scalar_fn,
|
||||
&|_, _| true,
|
||||
);
|
||||
}
|
||||
|
||||
fn assign<const LANES: usize>() {
|
||||
test_helpers::test_binary_elementwise(
|
||||
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign>::$fn_assign(&mut a, b); a },
|
||||
@ -61,14 +45,6 @@ macro_rules! impl_binary_op_test {
|
||||
&|_, _| true,
|
||||
);
|
||||
}
|
||||
|
||||
fn assign_scalar_rhs<const LANES: usize>() {
|
||||
test_helpers::test_binary_scalar_rhs_elementwise(
|
||||
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a },
|
||||
&$scalar_fn,
|
||||
&|_, _| true,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -99,22 +75,6 @@ macro_rules! impl_binary_checked_op_test {
|
||||
);
|
||||
}
|
||||
|
||||
fn scalar_rhs<const LANES: usize>() {
|
||||
test_helpers::test_binary_scalar_rhs_elementwise(
|
||||
&<Simd<$scalar, LANES> as core::ops::$trait<$scalar>>::$fn,
|
||||
&$scalar_fn,
|
||||
&|x, y| x.iter().all(|x| $check_fn(*x, y)),
|
||||
);
|
||||
}
|
||||
|
||||
fn scalar_lhs<const LANES: usize>() {
|
||||
test_helpers::test_binary_scalar_lhs_elementwise(
|
||||
&<$scalar as core::ops::$trait<Simd<$scalar, LANES>>>::$fn,
|
||||
&$scalar_fn,
|
||||
&|x, y| y.iter().all(|y| $check_fn(x, *y)),
|
||||
);
|
||||
}
|
||||
|
||||
fn assign<const LANES: usize>() {
|
||||
test_helpers::test_binary_elementwise(
|
||||
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign>::$fn_assign(&mut a, b); a },
|
||||
@ -122,14 +82,6 @@ macro_rules! impl_binary_checked_op_test {
|
||||
&|x, y| x.iter().zip(y.iter()).all(|(x, y)| $check_fn(*x, *y)),
|
||||
)
|
||||
}
|
||||
|
||||
fn assign_scalar_rhs<const LANES: usize>() {
|
||||
test_helpers::test_binary_scalar_rhs_elementwise(
|
||||
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign<$scalar>>::$fn_assign(&mut a, b); a },
|
||||
&$scalar_fn,
|
||||
&|x, y| x.iter().all(|x| $check_fn(*x, y)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user