Merge pull request #368 from rust-lang/remove-generic-const-exprs

Remove `generic_const_exprs`
This commit is contained in:
Caleb Zulawski 2023-10-20 19:10:50 -04:00 committed by GitHub
commit 3e4e13c82f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 157 additions and 126 deletions

View file

@ -238,7 +238,7 @@ jobs:
run: cross test --verbose --target=${{ matrix.target }} --release
features:
name: "Check cargo features (${{ matrix.simd }} × ${{ matrix.features }})"
name: "Test cargo features (${{ matrix.simd }} × ${{ matrix.features }})"
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -249,12 +249,8 @@ jobs:
features:
- ""
- "--features std"
- "--features generic_const_exprs"
- "--features std --features generic_const_exprs"
- "--features all_lane_counts"
- "--features all_lane_counts --features std"
- "--features all_lane_counts --features generic_const_exprs"
- "--features all_lane_counts --features std --features generic_const_exprs"
- "--all-features"
steps:
- uses: actions/checkout@v2
@ -266,9 +262,9 @@ jobs:
run: echo "CPU_FEATURE=$(lscpu | grep -o avx512[a-z]* | sed s/avx/+avx/ | tr '\n' ',' )" >> $GITHUB_ENV
- name: Check build
if: ${{ matrix.simd == '' }}
run: RUSTFLAGS="-Dwarnings" cargo check --all-targets --no-default-features ${{ matrix.features }}
run: RUSTFLAGS="-Dwarnings" cargo test --all-targets --no-default-features ${{ matrix.features }}
- name: Check AVX
if: ${{ matrix.simd == 'avx512' && contains(env.CPU_FEATURE, 'avx512') }}
run: |
echo "Found AVX features: $CPU_FEATURE"
RUSTFLAGS="-Dwarnings -Ctarget-feature=$CPU_FEATURE" cargo check --all-targets --no-default-features ${{ matrix.features }}
RUSTFLAGS="-Dwarnings -Ctarget-feature=$CPU_FEATURE" cargo test --all-targets --no-default-features ${{ matrix.features }}

View file

@ -12,7 +12,6 @@ license = "MIT OR Apache-2.0"
default = ["as_crate"]
as_crate = []
std = []
generic_const_exprs = []
all_lane_counts = []
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]

View file

@ -14,8 +14,6 @@
strict_provenance,
ptr_metadata
)]
#![cfg_attr(feature = "generic_const_exprs", feature(generic_const_exprs))]
#![cfg_attr(feature = "generic_const_exprs", allow(incomplete_features))]
#![warn(missing_docs, clippy::missing_inline_in_public_items)] // basically all items, really
#![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)]
#![allow(internal_features)]

View file

@ -13,10 +13,7 @@
mod mask_impl;
mod to_bitmask;
pub use to_bitmask::ToBitMask;
#[cfg(feature = "generic_const_exprs")]
pub use to_bitmask::{bitmask_len, ToBitMaskArray};
pub use to_bitmask::{ToBitMask, ToBitMaskArray};
use crate::simd::{intrinsics, LaneCount, Simd, SimdElement, SimdPartialEq, SupportedLaneCount};
use core::cmp::Ordering;

View file

@ -119,7 +119,6 @@ where
unsafe { Self(intrinsics::simd_bitmask(value), PhantomData) }
}
#[cfg(feature = "generic_const_exprs")]
#[inline]
#[must_use = "method returns a new array and does not mutate the original value"]
pub fn to_bitmask_array<const N: usize>(self) -> [u8; N] {
@ -129,7 +128,6 @@ where
unsafe { core::mem::transmute_copy(&self.0) }
}
#[cfg(feature = "generic_const_exprs")]
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
pub fn from_bitmask_array<const N: usize>(bitmask: [u8; N]) -> Self {

View file

@ -1,12 +1,9 @@
//! Masks that take up full SIMD vector registers.
use super::MaskElement;
use super::{to_bitmask::ToBitMaskArray, MaskElement};
use crate::simd::intrinsics;
use crate::simd::{LaneCount, Simd, SupportedLaneCount, ToBitMask};
#[cfg(feature = "generic_const_exprs")]
use crate::simd::ToBitMaskArray;
#[repr(transparent)]
pub struct Mask<T, const LANES: usize>(Simd<T, LANES>)
where
@ -145,23 +142,19 @@ where
unsafe { Mask(intrinsics::simd_cast(self.0)) }
}
#[cfg(feature = "generic_const_exprs")]
#[inline]
#[must_use = "method returns a new array and does not mutate the original value"]
pub fn to_bitmask_array<const N: usize>(self) -> [u8; N]
where
super::Mask<T, LANES>: ToBitMaskArray,
[(); <super::Mask<T, LANES> as ToBitMaskArray>::BYTES]: Sized,
{
assert_eq!(<super::Mask<T, LANES> as ToBitMaskArray>::BYTES, N);
// Safety: N is the correct bitmask size
// Safety: Bytes is the right size array
unsafe {
// Compute the bitmask
let bitmask: [u8; <super::Mask<T, LANES> as ToBitMaskArray>::BYTES] =
let bitmask: <super::Mask<T, LANES> as ToBitMaskArray>::BitMaskArray =
intrinsics::simd_bitmask(self.0);
// Transmute to the return type, previously asserted to be the same size
// Transmute to the return type
let mut bitmask: [u8; N] = core::mem::transmute_copy(&bitmask);
// LLVM assumes bit order should match endianness
@ -175,17 +168,13 @@ where
}
}
#[cfg(feature = "generic_const_exprs")]
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
pub fn from_bitmask_array<const N: usize>(mut bitmask: [u8; N]) -> Self
where
super::Mask<T, LANES>: ToBitMaskArray,
[(); <super::Mask<T, LANES> as ToBitMaskArray>::BYTES]: Sized,
{
assert_eq!(<super::Mask<T, LANES> as ToBitMaskArray>::BYTES, N);
// Safety: N is the correct bitmask size
// Safety: Bytes is the right size array
unsafe {
// LLVM assumes bit order should match endianness
if cfg!(target_endian = "big") {
@ -194,8 +183,8 @@ where
}
}
// Transmute to the bitmask type, previously asserted to be the same size
let bitmask: [u8; <super::Mask<T, LANES> as ToBitMaskArray>::BYTES] =
// Transmute to the bitmask
let bitmask: <super::Mask<T, LANES> as ToBitMaskArray>::BitMaskArray =
core::mem::transmute_copy(&bitmask);
// Compute the regular mask

View file

@ -1,5 +1,6 @@
use super::{mask_impl, Mask, MaskElement};
use crate::simd::{LaneCount, SupportedLaneCount};
use core::borrow::{Borrow, BorrowMut};
mod sealed {
pub trait Sealed {}
@ -30,19 +31,26 @@ pub trait ToBitMask: Sealed {
/// Converts masks to and from byte array bitmasks.
///
/// Each bit of the bitmask corresponds to a mask lane, starting with the LSB of the first byte.
#[cfg(feature = "generic_const_exprs")]
pub trait ToBitMaskArray: Sealed {
/// The length of the bitmask array.
const BYTES: usize;
/// The bitmask array.
type BitMaskArray: Copy
+ Unpin
+ Send
+ Sync
+ AsRef<[u8]>
+ AsMut<[u8]>
+ Borrow<[u8]>
+ BorrowMut<[u8]>
+ 'static;
/// Converts a mask to a bitmask.
fn to_bitmask_array(self) -> [u8; Self::BYTES];
fn to_bitmask_array(self) -> Self::BitMaskArray;
/// Converts a bitmask to a mask.
fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self;
fn from_bitmask_array(bitmask: Self::BitMaskArray) -> Self;
}
macro_rules! impl_integer_intrinsic {
macro_rules! impl_integer {
{ $(impl ToBitMask<BitMask=$int:ty> for Mask<_, $lanes:literal>)* } => {
$(
impl<T: MaskElement> ToBitMask for Mask<T, $lanes> {
@ -62,7 +70,27 @@ macro_rules! impl_integer_intrinsic {
}
}
impl_integer_intrinsic! {
macro_rules! impl_array {
{ $(impl ToBitMaskArray<Bytes=$int:literal> for Mask<_, $lanes:literal>)* } => {
$(
impl<T: MaskElement> ToBitMaskArray for Mask<T, $lanes> {
type BitMaskArray = [u8; $int];
#[inline]
fn to_bitmask_array(self) -> Self::BitMaskArray {
self.0.to_bitmask_array()
}
#[inline]
fn from_bitmask_array(bitmask: Self::BitMaskArray) -> Self {
Self(mask_impl::Mask::from_bitmask_array(bitmask))
}
}
)*
}
}
impl_integer! {
impl ToBitMask<BitMask=u8> for Mask<_, 1>
impl ToBitMask<BitMask=u8> for Mask<_, 2>
impl ToBitMask<BitMask=u8> for Mask<_, 4>
@ -72,27 +100,12 @@ impl_integer_intrinsic! {
impl ToBitMask<BitMask=u64> for Mask<_, 64>
}
/// Returns the minimum number of bytes in a bitmask with `lanes` lanes.
#[cfg(feature = "generic_const_exprs")]
#[allow(clippy::missing_inline_in_public_items)]
pub const fn bitmask_len(lanes: usize) -> usize {
(lanes + 7) / 8
}
#[cfg(feature = "generic_const_exprs")]
impl<T: MaskElement, const LANES: usize> ToBitMaskArray for Mask<T, LANES>
where
LaneCount<LANES>: SupportedLaneCount,
{
const BYTES: usize = bitmask_len(LANES);
#[inline]
fn to_bitmask_array(self) -> [u8; Self::BYTES] {
self.0.to_bitmask_array()
}
#[inline]
fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self {
Mask(mask_impl::Mask::from_bitmask_array(bitmask))
}
impl_array! {
impl ToBitMaskArray<Bytes=1> for Mask<_, 1>
impl ToBitMaskArray<Bytes=1> for Mask<_, 2>
impl ToBitMaskArray<Bytes=1> for Mask<_, 4>
impl ToBitMaskArray<Bytes=1> for Mask<_, 8>
impl ToBitMaskArray<Bytes=2> for Mask<_, 16>
impl ToBitMaskArray<Bytes=4> for Mask<_, 32>
impl ToBitMaskArray<Bytes=8> for Mask<_, 64>
}

View file

@ -3,9 +3,6 @@ mod swizzle;
pub(crate) mod intrinsics;
#[cfg(feature = "generic_const_exprs")]
mod to_bytes;
mod alias;
mod cast;
mod elements;
@ -18,6 +15,7 @@ mod ops;
mod ord;
mod select;
mod swizzle_dyn;
mod to_bytes;
mod vector;
mod vendor;
@ -37,5 +35,6 @@ pub mod simd {
pub use crate::core_simd::ord::*;
pub use crate::core_simd::swizzle::*;
pub use crate::core_simd::swizzle_dyn::*;
pub use crate::core_simd::to_bytes::ToBytes;
pub use crate::core_simd::vector::*;
}

View file

@ -1,74 +1,116 @@
use crate::simd::SimdUint;
use crate::simd::{LaneCount, Simd, SimdElement, SimdFloat, SimdInt, SimdUint, SupportedLaneCount};
mod sealed {
use super::*;
pub trait Sealed {}
impl<T: SimdElement, const N: usize> Sealed for Simd<T, N> where LaneCount<N>: SupportedLaneCount {}
}
use sealed::Sealed;
/// Convert SIMD vectors to vectors of bytes
pub trait ToBytes: Sealed {
/// This type, reinterpreted as bytes.
type Bytes: Copy
+ Unpin
+ Send
+ Sync
+ AsRef<[u8]>
+ AsMut<[u8]>
+ SimdUint<Scalar = u8>
+ 'static;
/// Return the memory representation of this integer as a byte array in native byte
/// order.
fn to_ne_bytes(self) -> Self::Bytes;
/// Return the memory representation of this integer as a byte array in big-endian
/// (network) byte order.
fn to_be_bytes(self) -> Self::Bytes;
/// Return the memory representation of this integer as a byte array in little-endian
/// byte order.
fn to_le_bytes(self) -> Self::Bytes;
/// Create a native endian integer value from its memory representation as a byte array
/// in native endianness.
fn from_ne_bytes(bytes: Self::Bytes) -> Self;
/// Create an integer value from its representation as a byte array in big endian.
fn from_be_bytes(bytes: Self::Bytes) -> Self;
/// Create an integer value from its representation as a byte array in little endian.
fn from_le_bytes(bytes: Self::Bytes) -> Self;
}
macro_rules! swap_bytes {
{ f32, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) };
{ f64, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) };
{ $ty:ty, $x:expr } => { $x.swap_bytes() }
}
macro_rules! impl_to_bytes {
{ $ty:ty, $size:literal } => {
impl<const LANES: usize> crate::simd::Simd<$ty, LANES>
where
crate::simd::LaneCount<LANES>: crate::simd::SupportedLaneCount,
crate::simd::LaneCount<{{ $size * LANES }}>: crate::simd::SupportedLaneCount,
{
/// Return the memory representation of this integer as a byte array in native byte
/// order.
{ $ty:tt, 1 } => { impl_to_bytes! { $ty, 1 * [1, 2, 4, 8, 16, 32, 64] } };
{ $ty:tt, 2 } => { impl_to_bytes! { $ty, 2 * [1, 2, 4, 8, 16, 32] } };
{ $ty:tt, 4 } => { impl_to_bytes! { $ty, 4 * [1, 2, 4, 8, 16] } };
{ $ty:tt, 8 } => { impl_to_bytes! { $ty, 8 * [1, 2, 4, 8] } };
{ $ty:tt, 16 } => { impl_to_bytes! { $ty, 16 * [1, 2, 4] } };
{ $ty:tt, 32 } => { impl_to_bytes! { $ty, 32 * [1, 2] } };
{ $ty:tt, 64 } => { impl_to_bytes! { $ty, 64 * [1] } };
{ $ty:tt, $size:literal * [$($elems:literal),*] } => {
$(
impl ToBytes for Simd<$ty, $elems> {
type Bytes = Simd<u8, { $size * $elems }>;
#[inline]
pub fn to_ne_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> {
fn to_ne_bytes(self) -> Self::Bytes {
// Safety: transmuting between vectors is safe
unsafe { core::mem::transmute_copy(&self) }
unsafe { core::mem::transmute(self) }
}
/// Return the memory representation of this integer as a byte array in big-endian
/// (network) byte order.
#[inline]
pub fn to_be_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> {
let bytes = self.to_ne_bytes();
fn to_be_bytes(mut self) -> Self::Bytes {
if !cfg!(target_endian = "big") {
self = swap_bytes!($ty, self);
}
self.to_ne_bytes()
}
#[inline]
fn to_le_bytes(mut self) -> Self::Bytes {
if !cfg!(target_endian = "little") {
self = swap_bytes!($ty, self);
}
self.to_ne_bytes()
}
#[inline]
fn from_ne_bytes(bytes: Self::Bytes) -> Self {
// Safety: transmuting between vectors is safe
unsafe { core::mem::transmute(bytes) }
}
#[inline]
fn from_be_bytes(bytes: Self::Bytes) -> Self {
let ret = Self::from_ne_bytes(bytes);
if cfg!(target_endian = "big") {
bytes
ret
} else {
bytes.swap_bytes()
swap_bytes!($ty, ret)
}
}
/// Return the memory representation of this integer as a byte array in little-endian
/// byte order.
#[inline]
pub fn to_le_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> {
let bytes = self.to_ne_bytes();
fn from_le_bytes(bytes: Self::Bytes) -> Self {
let ret = Self::from_ne_bytes(bytes);
if cfg!(target_endian = "little") {
bytes
ret
} else {
bytes.swap_bytes()
swap_bytes!($ty, ret)
}
}
/// Create a native endian integer value from its memory representation as a byte array
/// in native endianness.
#[inline]
pub fn from_ne_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self {
// Safety: transmuting between vectors is safe
unsafe { core::mem::transmute_copy(&bytes) }
}
/// Create an integer value from its representation as a byte array in big endian.
#[inline]
pub fn from_be_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self {
let bytes = if cfg!(target_endian = "big") {
bytes
} else {
bytes.swap_bytes()
};
Self::from_ne_bytes(bytes)
}
/// Create an integer value from its representation as a byte array in little endian.
#[inline]
pub fn from_le_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self {
let bytes = if cfg!(target_endian = "little") {
bytes
} else {
bytes.swap_bytes()
};
Self::from_ne_bytes(bytes)
}
}
)*
}
}
@ -89,3 +131,6 @@ impl_to_bytes! { i64, 8 }
impl_to_bytes! { isize, 4 }
#[cfg(target_pointer_width = "64")]
impl_to_bytes! { isize, 8 }
impl_to_bytes! { f32, 4 }
impl_to_bytes! { f64, 8 }

View file

@ -125,7 +125,6 @@ macro_rules! test_mask_api {
cast_impl::<isize>();
}
#[cfg(feature = "generic_const_exprs")]
#[test]
fn roundtrip_bitmask_array_conversion() {
use core_simd::simd::ToBitMaskArray;

View file

@ -1,8 +1,6 @@
#![feature(portable_simd, generic_const_exprs, adt_const_params)]
#![allow(incomplete_features)]
#![cfg(feature = "generic_const_exprs")]
#![feature(portable_simd)]
use core_simd::simd::Simd;
use core_simd::simd::{Simd, ToBytes};
#[test]
fn byte_convert() {