Skip to content

Commit f336406

Browse files
committed
Add aarch64 workarounds
1 parent 227a9d9 commit f336406

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

crates/core_simd/src/ops.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,47 @@ macro_rules! int_divrem_guard {
9696
// Nice base case to make it easy to const-fold away the other branch.
9797
$rhs
9898
};
99-
// Safety: $lhs and rhs are vectors
100-
unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) }
99+
100+
// aarch64 fails for arbitrary `v % 0` for non-powers-of-two
101+
#[cfg(target_arch = "aarch64")]
102+
{
103+
const { assert!(Self::LEN <= 64) };
104+
if Self::LEN == 1 {
105+
// Safety: $lhs and rhs are vectors
106+
let x: Simd::<_, 1> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<1>(Default::default()), rhs.resize::<1>(Default::default())) };
107+
x.resize(Default::default())
108+
} else if Self::LEN <= 2 {
109+
// Safety: $lhs and rhs are vectors
110+
let x: Simd::<_, 2> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<2>(Default::default()), rhs.resize::<2>(Default::default())) };
111+
x.resize(Default::default())
112+
} else if Self::LEN <= 4 {
113+
// Safety: $lhs and rhs are vectors
114+
let x: Simd::<_, 4> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<4>(Default::default()), rhs.resize::<4>(Default::default())) };
115+
x.resize(Default::default())
116+
} else if Self::LEN <= 8 {
117+
// Safety: $lhs and rhs are vectors
118+
let x: Simd::<_, 8> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<8>(Default::default()), rhs.resize::<8>(Default::default())) };
119+
x.resize(Default::default())
120+
} else if Self::LEN <= 16 {
121+
// Safety: $lhs and rhs are vectors
122+
let x: Simd::<_, 16> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<16>(Default::default()), rhs.resize::<16>(Default::default())) };
123+
x.resize(Default::default())
124+
} else if Self::LEN <= 32 {
125+
// Safety: $lhs and rhs are vectors
126+
let x: Simd::<_, 32> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<32>(Default::default()), rhs.resize::<32>(Default::default())) };
127+
x.resize(Default::default())
128+
} else {
129+
// Safety: $lhs and rhs are vectors
130+
let x: Simd::<_, 64> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<64>(Default::default()), rhs.resize::<64>(Default::default())) };
131+
x.resize(Default::default())
132+
}
133+
}
134+
135+
#[cfg(not(target_arch = "aarch64"))]
136+
{
137+
// Safety: $lhs and rhs are vectors
138+
unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) }
139+
}
101140
}
102141
};
103142
}

crates/core_simd/src/simd/num/float.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,13 +255,41 @@ macro_rules! impl_trait {
255255
type Bits = Simd<$bits_ty, N>;
256256
type Cast<T: SimdElement> = Simd<T, N>;
257257

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

266+
// https://github.com/llvm/llvm-project/issues/94694
267+
#[cfg(target_arch = "aarch64")]
268+
#[inline]
269+
fn cast<T: SimdCast>(self) -> Self::Cast<T>
270+
{
271+
const { assert!(N <= 64) };
272+
if N <= 2 || N == 4 || N == 8 || N == 16 || N == 32 || N == 64 {
273+
// Safety: supported types are guaranteed by SimdCast
274+
unsafe { core::intrinsics::simd::simd_as(self) }
275+
} else if N < 4 {
276+
let x = self.resize::<4>(Default::default()).cast();
277+
x.resize::<N>(x[0])
278+
} else if N < 8 {
279+
let x = self.resize::<8>(Default::default()).cast();
280+
x.resize::<N>(x[0])
281+
} else if N < 16 {
282+
let x = self.resize::<16>(Default::default()).cast();
283+
x.resize::<N>(x[0])
284+
} else if N < 32 {
285+
let x = self.resize::<32>(Default::default()).cast();
286+
x.resize::<N>(x[0])
287+
} else {
288+
let x = self.resize::<64>(Default::default()).cast();
289+
x.resize::<N>(x[0])
290+
}
291+
}
292+
265293
#[inline]
266294
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
267295
unsafe fn to_int_unchecked<I: SimdCast>(self) -> Self::Cast<I>

0 commit comments

Comments
 (0)