Skip to content

Sync portable-simd to 2023 July 07 #113437

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

Merged
merged 46 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
af2bc4e
Merge commit 'a8385522ade6f67853edac730b5bf164ddb298fd' into simd-rem…
workingjubilee Dec 3, 2021
35883a7
Merge commit '533f0fc81ab9ba097779fcd27c8f9ea12261fef5' into psimd
petrochenkov Dec 17, 2021
efb20c2
Sync rust-lang/portable-simd@03f6fbb21e6050da2a05b3ce8f480c020b384916
workingjubilee Jan 27, 2022
8adbb99
Switch bootstrap cfgs
Mark-Simulacrum Feb 23, 2022
754e077
Sync rust-lang/portable-simd@5f49d4c8435a25d804b2f375e949cb25479f5be9
workingjubilee Feb 28, 2022
ebb7423
Rollup merge of #94452 - workingjubilee:sync-simd-bitmasks, r=working…
Dylan-DPC Mar 1, 2022
700972b
Fix unused_doc_comments lint errors
GuillaumeGomez Mar 2, 2022
c43129f
Use implicit capture syntax in format_args
mahmoud-moursy Feb 12, 2022
94c7da0
Sync portable-simd to rust-lang/portable-simd@72df4c45056a8bc0d1b3f06…
workingjubilee Mar 13, 2022
62e239c
portable-simd: use simd_arith_offset to avoid ptr-int transmutation
RalfJung Apr 12, 2022
352e7b3
Finish bumping stage0
Mark-Simulacrum May 20, 2022
210275c
Sync core::simd up to rust-lang/portable-simd@2e081db92aa3ee0a4563bc2…
workingjubilee Jul 21, 2022
e2aec07
Fix a bunch of typo
dzvon Aug 18, 2022
1a6a069
separate the receiver from arguments in HIR under /clippy
TaKO8Ki Sep 1, 2022
6afcb85
Fix rustdoc lints
Mark-Simulacrum Nov 2, 2022
3cb40e5
Remove unnecessary `&format!`
nvzqz Jan 22, 2023
ddcb68a
Match unmatched backticks in library/
est31 Mar 3, 2023
2806570
remove some unneeded imports
kadiwa4 Aug 9, 2022
92a6d25
Merge from rustc
oli-obk Apr 17, 2023
a0d853c
Merge from rustc
RalfJung Apr 26, 2023
a2cdcd5
Make sure that signatures aren't accidental refinements
compiler-errors Apr 28, 2023
1ff41d3
Merge from rustc
RalfJung Apr 30, 2023
a978408
Sync portable-simd to 2023 May 10
workingjubilee May 11, 2023
c7f6aae
Correct swizzle_dyn cfg for armv7 neon
workingjubilee May 12, 2023
b3b5cfc
Add a prelude
calebzulawski May 3, 2023
9e818d6
Ignore doctest
calebzulawski May 3, 2023
c55e19c
Add Simd, Mask, simd_swizzle to prelude
calebzulawski May 3, 2023
048264e
Hide repr attribute from doc of types without guaranteed repr
dtolnay Feb 5, 2023
6626cd8
Remove cast_ptr in favor of cast which acts like pointer::cast. Move …
calebzulawski May 20, 2023
f4ee1ab
Simplify to_int_unchecked
calebzulawski May 20, 2023
c0b7df5
Add `#[inline]` to functions which were missing it, and `#[track_call…
thomcc May 7, 2023
0315db3
Re-add missing #[must_use]
calebzulawski May 21, 2023
cd3c67b
Merge pull request #347 from thomcc/attrs
calebzulawski May 21, 2023
1af32f0
Fix build error on big endian arm/aarch64
taiki-e May 30, 2023
ed2ee7a
Explicit set `workspace.resolver = "1"`
weihanglo May 30, 2023
5161f2e
Merge pull request #350 from rust-lang/cast
calebzulawski May 31, 2023
d975d8f
Merge pull request #348 from taiki-e/arm-big
calebzulawski Jun 1, 2023
73d7eb5
Merge pull request #344 from rust-lang/prelude
calebzulawski Jun 1, 2023
0368a8c
Merge branch 'master' into sync-upstream-2023-06-07
calebzulawski Jun 8, 2023
eb0041d
Format
calebzulawski Jun 8, 2023
2b55e03
Merge pull request #353 from rust-lang/sync-upstream-2023-06-07
workingjubilee Jul 7, 2023
f2f9bd7
Disable MIPS jobs in CI
workingjubilee Jul 7, 2023
789c38f
Fixed cast imports in doctest (rust-lang/portable-simd#355)
workingjubilee Jul 7, 2023
7c7dbe0
Remove unused import
workingjubilee Jul 7, 2023
8765f91
Sync portable-simd to 2023 July 07
workingjubilee Jul 7, 2023
37fea34
Use new std::simd fn in miri tests
workingjubilee Jul 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions library/portable-simd/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ jobs:
- i586-unknown-linux-gnu
- aarch64-unknown-linux-gnu
- armv7-unknown-linux-gnueabihf
- mips-unknown-linux-gnu
- mips64-unknown-linux-gnuabi64
# non-nightly since https://github.com/rust-lang/rust/pull/113274
# - mips-unknown-linux-gnu
# - mips64-unknown-linux-gnuabi64
- powerpc-unknown-linux-gnu
- powerpc64-unknown-linux-gnu
- riscv64gc-unknown-linux-gnu
Expand Down Expand Up @@ -191,8 +192,8 @@ jobs:
# Note: The issue above means neither of these mips targets will use
# MSA (mips simd) but MIPS uses a nonstandard binary representation
# for NaNs which makes it worth testing on despite that.
- mips-unknown-linux-gnu
- mips64-unknown-linux-gnuabi64
# - mips-unknown-linux-gnu
# - mips64-unknown-linux-gnuabi64
- riscv64gc-unknown-linux-gnu
# TODO this test works, but it appears to time out
# - powerpc-unknown-linux-gnu
Expand Down
74 changes: 35 additions & 39 deletions library/portable-simd/crates/core_simd/src/cast.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,51 @@
use crate::simd::SimdElement;

mod sealed {
/// Cast vector elements to other types.
///
/// # Safety
/// Implementing this trait asserts that the type is a valid vector element for the `simd_cast`
/// or `simd_as` intrinsics.
pub unsafe trait Sealed {}
}
use sealed::Sealed;

/// Supporting trait for `Simd::cast`. Typically doesn't need to be used directly.
///
/// # Safety
/// Implementing this trait asserts that the type is a valid vector element for the `simd_cast` or
/// `simd_as` intrinsics.
pub unsafe trait SimdCast: SimdElement {}
pub trait SimdCast: Sealed + SimdElement {}

// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for i8 {}
unsafe impl Sealed for i8 {}
impl SimdCast for i8 {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for i16 {}
unsafe impl Sealed for i16 {}
impl SimdCast for i16 {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for i32 {}
unsafe impl Sealed for i32 {}
impl SimdCast for i32 {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for i64 {}
unsafe impl Sealed for i64 {}
impl SimdCast for i64 {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for isize {}
unsafe impl Sealed for isize {}
impl SimdCast for isize {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for u8 {}
unsafe impl Sealed for u8 {}
impl SimdCast for u8 {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for u16 {}
unsafe impl Sealed for u16 {}
impl SimdCast for u16 {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for u32 {}
unsafe impl Sealed for u32 {}
impl SimdCast for u32 {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for u64 {}
unsafe impl Sealed for u64 {}
impl SimdCast for u64 {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for usize {}
unsafe impl Sealed for usize {}
impl SimdCast for usize {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for f32 {}
unsafe impl Sealed for f32 {}
impl SimdCast for f32 {}
// Safety: primitive number types can be cast to other primitive number types
unsafe impl SimdCast for f64 {}

/// Supporting trait for `Simd::cast_ptr`. Typically doesn't need to be used directly.
///
/// # Safety
/// Implementing this trait asserts that the type is a valid vector element for the `simd_cast_ptr`
/// intrinsic.
pub unsafe trait SimdCastPtr<T> {}

// Safety: pointers can be cast to other pointer types
unsafe impl<T, U> SimdCastPtr<T> for *const U
where
U: core::ptr::Pointee,
T: core::ptr::Pointee<Metadata = U::Metadata>,
{
}
// Safety: pointers can be cast to other pointer types
unsafe impl<T, U> SimdCastPtr<T> for *mut U
where
U: core::ptr::Pointee,
T: core::ptr::Pointee<Metadata = U::Metadata>,
{
}
unsafe impl Sealed for f64 {}
impl SimdCast for f64 {}
30 changes: 26 additions & 4 deletions library/portable-simd/crates/core_simd/src/elements/const_ptr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::sealed::Sealed;
use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SupportedLaneCount};
use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SimdUint, SupportedLaneCount};

/// Operations on SIMD vectors of constant pointers.
pub trait SimdConstPtr: Copy + Sealed {
Expand All @@ -9,6 +9,9 @@ pub trait SimdConstPtr: Copy + Sealed {
/// Vector of `isize` with the same number of lanes.
type Isize;

/// Vector of const pointers with the same number of lanes.
type CastPtr<T>;

/// Vector of mutable pointers to the same type.
type MutPtr;

Expand All @@ -18,6 +21,11 @@ pub trait SimdConstPtr: Copy + Sealed {
/// Returns `true` for each lane that is null.
fn is_null(self) -> Self::Mask;

/// Casts to a pointer of another type.
///
/// Equivalent to calling [`pointer::cast`] on each lane.
fn cast<T>(self) -> Self::CastPtr<T>;

/// Changes constness without changing the type.
///
/// Equivalent to calling [`pointer::cast_mut`] on each lane.
Expand Down Expand Up @@ -78,6 +86,7 @@ where
{
type Usize = Simd<usize, LANES>;
type Isize = Simd<isize, LANES>;
type CastPtr<U> = Simd<*const U, LANES>;
type MutPtr = Simd<*mut T, LANES>;
type Mask = Mask<isize, LANES>;

Expand All @@ -86,9 +95,22 @@ where
Simd::splat(core::ptr::null()).simd_eq(self)
}

#[inline]
fn cast<U>(self) -> Self::CastPtr<U> {
// SimdElement currently requires zero-sized metadata, so this should never fail.
// If this ever changes, `simd_cast_ptr` should produce a post-mono error.
use core::{mem::size_of, ptr::Pointee};
assert_eq!(size_of::<<T as Pointee>::Metadata>(), 0);
assert_eq!(size_of::<<U as Pointee>::Metadata>(), 0);

// Safety: pointers can be cast
unsafe { intrinsics::simd_cast_ptr(self) }
}

#[inline]
fn cast_mut(self) -> Self::MutPtr {
self.cast_ptr()
// Safety: pointers can be cast
unsafe { intrinsics::simd_cast_ptr(self) }
}

#[inline]
Expand All @@ -106,9 +128,9 @@ where
// In the mean-time, this operation is defined to be "as if" it was
// a wrapping_offset, so we can emulate it as such. This should properly
// restore pointer provenance even under today's compiler.
self.cast_ptr::<*const u8>()
self.cast::<u8>()
.wrapping_offset(addr.cast::<isize>() - self.addr().cast::<isize>())
.cast_ptr()
.cast()
}

#[inline]
Expand Down
67 changes: 66 additions & 1 deletion library/portable-simd/crates/core_simd/src/elements/float.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::sealed::Sealed;
use crate::simd::{
intrinsics, LaneCount, Mask, Simd, SimdElement, SimdPartialEq, SimdPartialOrd,
intrinsics, LaneCount, Mask, Simd, SimdCast, SimdElement, SimdPartialEq, SimdPartialOrd,
SupportedLaneCount,
};

Expand All @@ -15,6 +15,53 @@ pub trait SimdFloat: Copy + Sealed {
/// Bit representation of this SIMD vector type.
type Bits;

/// A SIMD vector with a different element type.
type Cast<T: SimdElement>;

/// Performs elementwise conversion of this vector's elements to another SIMD-valid type.
///
/// This follows the semantics of Rust's `as` conversion for floats (truncating or saturating
/// at the limits) for each element.
///
/// # Example
/// ```
/// # #![feature(portable_simd)]
/// # #[cfg(feature = "as_crate")] use core_simd::simd;
/// # #[cfg(not(feature = "as_crate"))] use core::simd;
/// # use simd::{SimdFloat, SimdInt, Simd};
/// let floats: Simd<f32, 4> = Simd::from_array([1.9, -4.5, f32::INFINITY, f32::NAN]);
/// let ints = floats.cast::<i32>();
/// assert_eq!(ints, Simd::from_array([1, -4, i32::MAX, 0]));
///
/// // Formally equivalent, but `Simd::cast` can optimize better.
/// assert_eq!(ints, Simd::from_array(floats.to_array().map(|x| x as i32)));
///
/// // The float conversion does not round-trip.
/// let floats_again = ints.cast();
/// assert_ne!(floats, floats_again);
/// assert_eq!(floats_again, Simd::from_array([1.0, -4.0, 2147483647.0, 0.0]));
/// ```
#[must_use]
fn cast<T: SimdCast>(self) -> Self::Cast<T>;

/// Rounds toward zero and converts to the same-width integer type, assuming that
/// the value is finite and fits in that type.
///
/// # Safety
/// The value must:
///
/// * Not be NaN
/// * Not be infinite
/// * Be representable in the return type, after truncating off its fractional part
///
/// If these requirements are infeasible or costly, consider using the safe function [cast],
/// which saturates on conversion.
///
/// [cast]: Simd::cast
unsafe fn to_int_unchecked<I: SimdCast>(self) -> Self::Cast<I>
where
Self::Scalar: core::convert::FloatToInt<I>;

/// Raw transmutation to an unsigned integer vector type with the
/// same size and number of lanes.
#[must_use = "method returns a new vector and does not mutate the original value"]
Expand Down Expand Up @@ -206,6 +253,24 @@ macro_rules! impl_trait {
type Mask = Mask<<$mask_ty as SimdElement>::Mask, LANES>;
type Scalar = $ty;
type Bits = Simd<$bits_ty, LANES>;
type Cast<T: SimdElement> = Simd<T, LANES>;

#[inline]
fn cast<T: SimdCast>(self) -> Self::Cast<T>
{
// Safety: supported types are guaranteed by SimdCast
unsafe { intrinsics::simd_as(self) }
}

#[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>
where
Self::Scalar: core::convert::FloatToInt<I>,
{
// Safety: supported types are guaranteed by SimdCast, the caller is responsible for the extra invariants
unsafe { intrinsics::simd_cast(self) }
}

#[inline]
fn to_bits(self) -> Simd<$bits_ty, LANES> {
Expand Down
19 changes: 18 additions & 1 deletion library/portable-simd/crates/core_simd/src/elements/int.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::sealed::Sealed;
use crate::simd::{
intrinsics, LaneCount, Mask, Simd, SimdElement, SimdPartialOrd, SupportedLaneCount,
intrinsics, LaneCount, Mask, Simd, SimdCast, SimdElement, SimdPartialOrd, SupportedLaneCount,
};

/// Operations on SIMD vectors of signed integers.
Expand All @@ -11,6 +11,16 @@ pub trait SimdInt: Copy + Sealed {
/// Scalar type contained by this SIMD vector type.
type Scalar;

/// A SIMD vector with a different element type.
type Cast<T: SimdElement>;

/// Performs elementwise conversion of this vector's elements to another SIMD-valid type.
///
/// This follows the semantics of Rust's `as` conversion for casting integers (wrapping to
/// other integer types, and saturating to float types).
#[must_use]
fn cast<T: SimdCast>(self) -> Self::Cast<T>;

/// Lanewise saturating add.
///
/// # Examples
Expand Down Expand Up @@ -198,6 +208,13 @@ macro_rules! impl_trait {
{
type Mask = Mask<<$ty as SimdElement>::Mask, LANES>;
type Scalar = $ty;
type Cast<T: SimdElement> = Simd<T, LANES>;

#[inline]
fn cast<T: SimdCast>(self) -> Self::Cast<T> {
// Safety: supported types are guaranteed by SimdCast
unsafe { intrinsics::simd_as(self) }
}

#[inline]
fn saturating_add(self, second: Self) -> Self {
Expand Down
30 changes: 26 additions & 4 deletions library/portable-simd/crates/core_simd/src/elements/mut_ptr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::sealed::Sealed;
use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SupportedLaneCount};
use crate::simd::{intrinsics, LaneCount, Mask, Simd, SimdPartialEq, SimdUint, SupportedLaneCount};

/// Operations on SIMD vectors of mutable pointers.
pub trait SimdMutPtr: Copy + Sealed {
Expand All @@ -9,6 +9,9 @@ pub trait SimdMutPtr: Copy + Sealed {
/// Vector of `isize` with the same number of lanes.
type Isize;

/// Vector of const pointers with the same number of lanes.
type CastPtr<T>;

/// Vector of constant pointers to the same type.
type ConstPtr;

Expand All @@ -18,6 +21,11 @@ pub trait SimdMutPtr: Copy + Sealed {
/// Returns `true` for each lane that is null.
fn is_null(self) -> Self::Mask;

/// Casts to a pointer of another type.
///
/// Equivalent to calling [`pointer::cast`] on each lane.
fn cast<T>(self) -> Self::CastPtr<T>;

/// Changes constness without changing the type.
///
/// Equivalent to calling [`pointer::cast_const`] on each lane.
Expand Down Expand Up @@ -73,6 +81,7 @@ where
{
type Usize = Simd<usize, LANES>;
type Isize = Simd<isize, LANES>;
type CastPtr<U> = Simd<*mut U, LANES>;
type ConstPtr = Simd<*const T, LANES>;
type Mask = Mask<isize, LANES>;

Expand All @@ -81,9 +90,22 @@ where
Simd::splat(core::ptr::null_mut()).simd_eq(self)
}

#[inline]
fn cast<U>(self) -> Self::CastPtr<U> {
// SimdElement currently requires zero-sized metadata, so this should never fail.
// If this ever changes, `simd_cast_ptr` should produce a post-mono error.
use core::{mem::size_of, ptr::Pointee};
assert_eq!(size_of::<<T as Pointee>::Metadata>(), 0);
assert_eq!(size_of::<<U as Pointee>::Metadata>(), 0);

// Safety: pointers can be cast
unsafe { intrinsics::simd_cast_ptr(self) }
}

#[inline]
fn cast_const(self) -> Self::ConstPtr {
self.cast_ptr()
// Safety: pointers can be cast
unsafe { intrinsics::simd_cast_ptr(self) }
}

#[inline]
Expand All @@ -101,9 +123,9 @@ where
// In the mean-time, this operation is defined to be "as if" it was
// a wrapping_offset, so we can emulate it as such. This should properly
// restore pointer provenance even under today's compiler.
self.cast_ptr::<*mut u8>()
self.cast::<u8>()
.wrapping_offset(addr.cast::<isize>() - self.addr().cast::<isize>())
.cast_ptr()
.cast()
}

#[inline]
Expand Down
Loading