Skip to content

Commit

Permalink
portable-simd: use simd_arith_offset to avoid ptr-int transmutation
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Apr 12, 2022
1 parent 7f945b2 commit e886dc5
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 0 deletions.
4 changes: 4 additions & 0 deletions library/portable-simd/crates/core_simd/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ extern "platform-intrinsic" {
/// xor
pub(crate) fn simd_xor<T>(x: T, y: T) -> T;

/// getelementptr (without inbounds)
#[cfg(not(bootstrap))]
pub(crate) fn simd_arith_offset<T, U>(ptrs: T, offsets: U) -> T;

/// fptoui/fptosi/uitofp/sitofp
/// casting floats to integers is truncating, so it is safe to convert values like e.g. 1.5
/// but the truncated value must fit in the target type or the result is poison.
Expand Down
11 changes: 11 additions & 0 deletions library/portable-simd/crates/core_simd/src/vector/ptr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! Private implementation details of public gather/scatter APIs.
#[cfg(not(bootstrap))]
use crate::simd::intrinsics;
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
#[cfg(bootstrap)]
use core::mem;

/// A vector of *const T.
Expand All @@ -21,12 +24,16 @@ where
#[inline]
#[must_use]
pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
#[cfg(bootstrap)]
// Safety: converting pointers to usize and vice-versa is safe
// (even if using that pointer is not)
unsafe {
let x: Simd<usize, LANES> = mem::transmute_copy(&self);
mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
}
#[cfg(not(bootstrap))]
// Safety: this intrinsic doesn't have a precondition
unsafe { intrinsics::simd_arith_offset(self, addend) }
}
}

Expand All @@ -49,11 +56,15 @@ where
#[inline]
#[must_use]
pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
#[cfg(bootstrap)]
// Safety: converting pointers to usize and vice-versa is safe
// (even if using that pointer is not)
unsafe {
let x: Simd<usize, LANES> = mem::transmute_copy(&self);
mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
}
#[cfg(not(bootstrap))]
// Safety: this intrinsic doesn't have a precondition
unsafe { intrinsics::simd_arith_offset(self, addend) }
}
}

0 comments on commit e886dc5

Please sign in to comment.