-
Notifications
You must be signed in to change notification settings - Fork 88
Fix layout of non-power-of-two length vectors #422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
227a9d9
f336406
9f7fec8
a49f77e
751c3b5
7f6a981
2a3b8ad
d7d060a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[build.env] | ||
passthrough = ["PROPTEST_CASES"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,7 +77,7 @@ macro_rules! int_divrem_guard { | |
( $lhs:ident, | ||
$rhs:ident, | ||
{ const PANIC_ZERO: &'static str = $zero:literal; | ||
$simd_call:ident | ||
$simd_call:ident, $op:tt | ||
}, | ||
$int:ident ) => { | ||
if $rhs.simd_eq(Simd::splat(0 as _)).any() { | ||
|
@@ -96,8 +96,23 @@ 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 div fails for arbitrary `v % 0`, mod fails when rhs is MIN, for non-powers-of-two | ||
// these operations aren't vectorized on aarch64 anyway | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are LLVM backend bugs, right? simd_div/simd_rem still should work the same on all targets? That seems worth tracking somewhere, having subtly buggy intrinsics is no good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also, theoretically LLVM should be able to generate SIMD code for division/remainder by a constant, by using the exact same fancy math as it would use for scalars (which it unfortunately currently does after scalarization of div ops for non-power-of-2 vectors), so once LLVM's bugs are fixed, I think we should switch back to generating SIMD ops. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, these are definitely backend bugs |
||
#[cfg(target_arch = "aarch64")] | ||
{ | ||
let mut out = Simd::splat(0 as _); | ||
for i in 0..Self::LEN { | ||
out[i] = $lhs[i] $op rhs[i]; | ||
} | ||
out | ||
} | ||
|
||
#[cfg(not(target_arch = "aarch64"))] | ||
{ | ||
// Safety: $lhs and rhs are vectors | ||
unsafe { core::intrinsics::simd::$simd_call($lhs, rhs) } | ||
} | ||
} | ||
}; | ||
} | ||
|
@@ -205,14 +220,14 @@ for_base_ops! { | |
impl Div::div { | ||
int_divrem_guard { | ||
const PANIC_ZERO: &'static str = "attempt to divide by zero"; | ||
simd_div | ||
simd_div, / | ||
} | ||
} | ||
|
||
impl Rem::rem { | ||
int_divrem_guard { | ||
const PANIC_ZERO: &'static str = "attempt to calculate the remainder with a divisor of zero"; | ||
simd_rem | ||
simd_rem, % | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,7 +99,7 @@ use crate::simd::{ | |
// directly constructing an instance of the type (i.e. `let vector = Simd(array)`) should be | ||
// avoided, as it will likely become illegal on `#[repr(simd)]` structs in the future. It also | ||
// causes rustc to emit illegal LLVM IR in some cases. | ||
#[repr(simd)] | ||
#[repr(simd, packed)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the plan for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK stdarch only uses power-of-2 vectors, where |
||
pub struct Simd<T, const N: usize>([T; N]) | ||
where | ||
LaneCount<N>: SupportedLaneCount, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#![feature(portable_simd)] | ||
|
||
macro_rules! layout_tests { | ||
{ $($mod:ident, $ty:ty,)* } => { | ||
$( | ||
mod $mod { | ||
test_helpers::test_lanes! { | ||
fn no_padding<const LANES: usize>() { | ||
assert_eq!( | ||
core::mem::size_of::<core_simd::simd::Simd::<$ty, LANES>>(), | ||
core::mem::size_of::<[$ty; LANES]>(), | ||
); | ||
} | ||
} | ||
} | ||
)* | ||
} | ||
} | ||
|
||
layout_tests! { | ||
i8, i8, | ||
i16, i16, | ||
i32, i32, | ||
i64, i64, | ||
isize, isize, | ||
u8, u8, | ||
u16, u16, | ||
u32, u32, | ||
u64, u64, | ||
usize, usize, | ||
f32, f32, | ||
f64, f64, | ||
mut_ptr, *mut (), | ||
const_ptr, *const (), | ||
} |
Uh oh!
There was an error while loading. Please reload this page.