Skip to content

Commit

Permalink
Add aarch64 workarounds
Browse files Browse the repository at this point in the history
  • Loading branch information
calebzulawski committed Jun 23, 2024
1 parent 4528e0f commit ce73c96
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
43 changes: 41 additions & 2 deletions crates/core_simd/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,47 @@ macro_rules! int_divrem_guard {
// Nice base case to make it easy to const-fold away the other branch.
$rhs
};
// Safety: $lhs and rhs are vectors
unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) }

// aarch64 fails for arbitrary `v % 0` for non-powers-of-two
#[cfg(target_arch = "aarch64")]
{
const { assert!(Self::LEN <= 64) };
if Self::LEN == 1 {
// Safety: $lhs and rhs are vectors
let x: Simd::<_, 1> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<1>(Default::default()), rhs.resize::<1>(Default::default())) };
x.resize(Default::default())
} else if Self::LEN <= 2 {
// Safety: $lhs and rhs are vectors
let x: Simd::<_, 2> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<2>(Default::default()), rhs.resize::<2>(Default::default())) };
x.resize(Default::default())
} else if Self::LEN <= 4 {
// Safety: $lhs and rhs are vectors
let x: Simd::<_, 4> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<4>(Default::default()), rhs.resize::<4>(Default::default())) };
x.resize(Default::default())
} else if Self::LEN <= 8 {
// Safety: $lhs and rhs are vectors
let x: Simd::<_, 8> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<8>(Default::default()), rhs.resize::<8>(Default::default())) };
x.resize(Default::default())
} else if Self::LEN <= 16 {
// Safety: $lhs and rhs are vectors
let x: Simd::<_, 16> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<16>(Default::default()), rhs.resize::<16>(Default::default())) };
x.resize(Default::default())
} else if Self::LEN <= 32 {
// Safety: $lhs and rhs are vectors
let x: Simd::<_, 32> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<32>(Default::default()), rhs.resize::<32>(Default::default())) };
x.resize(Default::default())
} else {
// Safety: $lhs and rhs are vectors
let x: Simd::<_, 64> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<64>(Default::default()), rhs.resize::<64>(Default::default())) };
x.resize(Default::default())
}
}

#[cfg(not(target_arch = "aarch64"))]
{
// Safety: $lhs and rhs are vectors
unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) }
}
}
};
}
Expand Down
28 changes: 28 additions & 0 deletions crates/core_simd/src/simd/num/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,13 +255,41 @@ macro_rules! impl_trait {
type Bits = Simd<$bits_ty, N>;
type Cast<T: SimdElement> = Simd<T, N>;

#[cfg(not(target_arch = "aarch64"))]
#[inline]
fn cast<T: SimdCast>(self) -> Self::Cast<T>
{
// Safety: supported types are guaranteed by SimdCast
unsafe { core::intrinsics::simd::simd_as(self) }
}

// https://github.com/llvm/llvm-project/issues/94694
#[cfg(target_arch = "aarch64")]
#[inline]
fn cast<T: SimdCast>(self) -> Self::Cast<T>
{
const { assert!(N <= 64) };
if N <= 2 || N == 4 || N == 8 || N == 16 || N == 32 || N == 64 {
// Safety: supported types are guaranteed by SimdCast
unsafe { core::intrinsics::simd::simd_as(self) }
} else if N < 4 {
let x = self.resize::<4>(Default::default()).cast();
x.resize::<N>(x[0])
} else if N < 8 {
let x = self.resize::<8>(Default::default()).cast();
x.resize::<N>(x[0])
} else if N < 16 {
let x = self.resize::<16>(Default::default()).cast();
x.resize::<N>(x[0])
} else if N < 32 {
let x = self.resize::<32>(Default::default()).cast();
x.resize::<N>(x[0])
} else {
let x = self.resize::<64>(Default::default()).cast();
x.resize::<N>(x[0])
}
}

#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
unsafe fn to_int_unchecked<I: SimdCast>(self) -> Self::Cast<I>
Expand Down

0 comments on commit ce73c96

Please sign in to comment.