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];
|
let sun = &mut sun[0];
|
||||||
for body in rest {
|
for body in rest {
|
||||||
let m_ratio = body.mass / SOLAR_MASS;
|
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;
|
let mut i = 0;
|
||||||
for j in 0..N_BODIES {
|
for j in 0..N_BODIES {
|
||||||
for k in j + 1..N_BODIES {
|
for k in j + 1..N_BODIES {
|
||||||
let f = r[i] * mag[i];
|
let f = r[i] * Simd::splat(mag[i]);
|
||||||
bodies[j].v -= f * bodies[k].mass;
|
bodies[j].v -= f * Simd::splat(bodies[k].mass);
|
||||||
bodies[k].v += f * bodies[j].mass;
|
bodies[k].v += f * Simd::splat(bodies[j].mass);
|
||||||
i += 1
|
i += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for body in bodies {
|
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 max = Simd::splat(MAX);
|
||||||
/// let unsat = x + max;
|
/// let unsat = x + max;
|
||||||
/// let sat = x.saturating_add(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);
|
/// assert_eq!(sat, max);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -37,7 +37,7 @@ macro_rules! impl_uint_arith {
|
|||||||
/// let max = Simd::splat(MAX);
|
/// let max = Simd::splat(MAX);
|
||||||
/// let unsat = x - max;
|
/// let unsat = x - max;
|
||||||
/// let sat = x.saturating_sub(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));
|
/// assert_eq!(sat, Simd::splat(0));
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn saturating_sub(self, second: Self) -> Self {
|
pub fn saturating_sub(self, second: Self) -> Self {
|
||||||
@ -105,7 +105,7 @@ macro_rules! impl_int_arith {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn abs(self) -> Self {
|
pub fn abs(self) -> Self {
|
||||||
const SHR: $ty = <$ty>::BITS as $ty - 1;
|
const SHR: $ty = <$ty>::BITS as $ty - 1;
|
||||||
let m = self >> SHR;
|
let m = self >> Simd::splat(SHR);
|
||||||
(self^m) - m
|
(self^m) - m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ macro_rules! impl_int_arith {
|
|||||||
pub fn saturating_abs(self) -> Self {
|
pub fn saturating_abs(self) -> Self {
|
||||||
// arith shift for -1 or 0 mask based on sign bit, giving 2s complement
|
// arith shift for -1 or 0 mask based on sign bit, giving 2s complement
|
||||||
const SHR: $ty = <$ty>::BITS as $ty - 1;
|
const SHR: $ty = <$ty>::BITS as $ty - 1;
|
||||||
let m = self >> SHR;
|
let m = self >> Simd::splat(SHR);
|
||||||
(self^m).saturating_sub(m)
|
(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
|
// remainder panics on zero divisor
|
||||||
impl_ref_ops! {
|
impl_ref_ops! {
|
||||||
impl<const LANES: usize> core::ops::Rem<Self> for Simd<$scalar, LANES>
|
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
|
// shifts panic on overflow
|
||||||
impl_ref_ops! {
|
impl_ref_ops! {
|
||||||
impl<const LANES: usize> core::ops::Shl<Self> for Simd<$scalar, LANES>
|
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_ref_ops! {
|
||||||
impl<const LANES: usize> core::ops::Shr<Self> for Simd<$scalar, LANES>
|
impl<const LANES: usize> core::ops::Shr<Self> for Simd<$scalar, LANES>
|
||||||
where
|
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 {
|
pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let x: Simd<usize, LANES> = mem::transmute_copy(&self);
|
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 {
|
pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let x: Simd<usize, LANES> = mem::transmute_copy(&self);
|
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>() {
|
fn assign<const LANES: usize>() {
|
||||||
test_helpers::test_binary_elementwise(
|
test_helpers::test_binary_elementwise(
|
||||||
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign>::$fn_assign(&mut a, b); a },
|
&|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,
|
&|_, _| 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>() {
|
fn assign<const LANES: usize>() {
|
||||||
test_helpers::test_binary_elementwise(
|
test_helpers::test_binary_elementwise(
|
||||||
&|mut a, b| { <Simd<$scalar, LANES> as core::ops::$trait_assign>::$fn_assign(&mut a, b); a },
|
&|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)),
|
&|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