Skip to content

Commit d513647

Browse files
committed
Add aarch64 workarounds
1 parent e3dabf5 commit d513647

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

crates/core_simd/src/ops.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,33 @@ 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+
const { assert!(Self::LEN <= 64) };
102+
if cfg!(not(target_arch = "aarch64")) || Self::LEN <= 2 {
103+
// Safety: $lhs and rhs are vectors
104+
unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) }
105+
} else if Self::LEN <= 4 {
106+
// Safety: $lhs and rhs are vectors
107+
let x: Simd::<_, 4> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<4>(Default::default()), rhs.resize::<4>(Default::default())) };
108+
x.resize(Default::default())
109+
} else if Self::LEN <= 8 {
110+
// Safety: $lhs and rhs are vectors
111+
let x: Simd::<_, 8> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<8>(Default::default()), rhs.resize::<8>(Default::default())) };
112+
x.resize(Default::default())
113+
} else if Self::LEN <= 16 {
114+
// Safety: $lhs and rhs are vectors
115+
let x: Simd::<_, 16> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<16>(Default::default()), rhs.resize::<16>(Default::default())) };
116+
x.resize(Default::default())
117+
} else if Self::LEN <= 32 {
118+
// Safety: $lhs and rhs are vectors
119+
let x: Simd::<_, 32> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<32>(Default::default()), rhs.resize::<32>(Default::default())) };
120+
x.resize(Default::default())
121+
} else {
122+
// Safety: $lhs and rhs are vectors
123+
let x: Simd::<_, 64> = unsafe { core::intrinsics::simd::$simd_call($lhs.resize::<64>(Default::default()), rhs.resize::<64>(Default::default())) };
124+
x.resize(Default::default())
125+
}
101126
}
102127
};
103128
}

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 {
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)