diff options
| author | bjorn3 <17426603+bjorn3@users.noreply.github.com> | 2022-09-05 16:13:36 +0000 |
|---|---|---|
| committer | bjorn3 <17426603+bjorn3@users.noreply.github.com> | 2022-09-05 16:13:36 +0000 |
| commit | 782b5fe7ac97554f7bf4b9121e985871e650ca41 (patch) | |
| tree | 3cb76f3866073280704fa2b6fda5adcb36b190d4 | |
| parent | 0980596271fd99665921052c8f666f7fb718a3cc (diff) | |
| download | rust-782b5fe7ac97554f7bf4b9121e985871e650ca41.tar.gz rust-782b5fe7ac97554f7bf4b9121e985871e650ca41.zip | |
Implement simd_saturating_{add,sub}
| -rw-r--r-- | patches/0001-portable-simd-Disable-unsupported-tests.patch | 104 | ||||
| -rw-r--r-- | src/intrinsics/mod.rs | 24 | ||||
| -rw-r--r-- | src/intrinsics/simd.rs | 17 |
3 files changed, 39 insertions, 106 deletions
diff --git a/patches/0001-portable-simd-Disable-unsupported-tests.patch b/patches/0001-portable-simd-Disable-unsupported-tests.patch index c75d5dda5ca..e23dea97694 100644 --- a/patches/0001-portable-simd-Disable-unsupported-tests.patch +++ b/patches/0001-portable-simd-Disable-unsupported-tests.patch @@ -11,110 +11,6 @@ Subject: [PATCH] Disable unsupported tests crates/core_simd/tests/masks.rs | 3 --- 5 files changed, 20 insertions(+), 3 deletions(-) -diff --git a/crates/core_simd/src/elements/int.rs b/crates/core_simd/src/elements/int.rs -index 9b8c37e..ea95f08 100644 ---- a/crates/core_simd/src/elements/int.rs -+++ b/crates/core_simd/src/elements/int.rs -@@ -11,6 +11,7 @@ pub trait SimdInt: Copy + Sealed { - /// Scalar type contained by this SIMD vector type. - type Scalar; - -+ /* - /// Lanewise saturating add. - /// - /// # Examples -@@ -45,6 +46,7 @@ pub trait SimdInt: Copy + Sealed { - /// assert_eq!(unsat, Simd::from_array([1, MAX, MIN, 0])); - /// assert_eq!(sat, Simd::from_array([MIN, MIN, MIN, 0])); - fn saturating_sub(self, second: Self) -> Self; -+ */ - - /// Lanewise absolute value, implemented in Rust. - /// Every lane becomes its absolute value. -@@ -61,6 +63,7 @@ pub trait SimdInt: Copy + Sealed { - /// ``` - fn abs(self) -> Self; - -+ /* - /// Lanewise saturating absolute value, implemented in Rust. - /// As abs(), except the MIN value becomes MAX instead of itself. - /// -@@ -96,6 +99,7 @@ pub trait SimdInt: Copy + Sealed { - /// assert_eq!(sat, Simd::from_array([MAX, 2, -3, MIN + 1])); - /// ``` - fn saturating_neg(self) -> Self; -+ */ - - /// Returns true for each positive lane and false if it is zero or negative. - fn is_positive(self) -> Self::Mask; -@@ -199,6 +203,7 @@ macro_rules! impl_trait { - type Mask = Mask<<$ty as SimdElement>::Mask, LANES>; - type Scalar = $ty; - -+ /* - #[inline] - fn saturating_add(self, second: Self) -> Self { - // Safety: `self` is a vector -@@ -210,6 +215,7 @@ macro_rules! impl_trait { - // Safety: `self` is a vector - unsafe { intrinsics::simd_saturating_sub(self, second) } - } -+ */ - - #[inline] - fn abs(self) -> Self { -@@ -218,6 +224,7 @@ macro_rules! impl_trait { - (self^m) - m - } - -+ /* - #[inline] - fn saturating_abs(self) -> Self { - // arith shift for -1 or 0 mask based on sign bit, giving 2s complement -@@ -230,6 +237,7 @@ macro_rules! impl_trait { - fn saturating_neg(self) -> Self { - Self::splat(0).saturating_sub(self) - } -+ */ - - #[inline] - fn is_positive(self) -> Self::Mask { -diff --git a/crates/core_simd/src/elements/uint.rs b/crates/core_simd/src/elements/uint.rs -index 21e7e76..0d6dee2 100644 ---- a/crates/core_simd/src/elements/uint.rs -+++ b/crates/core_simd/src/elements/uint.rs -@@ -6,6 +6,7 @@ pub trait SimdUint: Copy + Sealed { - /// Scalar type contained by this SIMD vector type. - type Scalar; - -+ /* - /// Lanewise saturating add. - /// - /// # Examples -@@ -40,6 +41,7 @@ pub trait SimdUint: Copy + Sealed { - /// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0])); - /// assert_eq!(sat, Simd::splat(0)); - fn saturating_sub(self, second: Self) -> Self; -+ */ - - /// Returns the sum of the lanes of the vector, with wrapping addition. - fn reduce_sum(self) -> Self::Scalar; -@@ -78,6 +80,7 @@ macro_rules! impl_trait { - { - type Scalar = $ty; - -+ /* - #[inline] - fn saturating_add(self, second: Self) -> Self { - // Safety: `self` is a vector -@@ -89,6 +92,7 @@ macro_rules! impl_trait { - // Safety: `self` is a vector - unsafe { intrinsics::simd_saturating_sub(self, second) } - } -+ */ - - #[inline] - fn reduce_sum(self) -> Self::Scalar { diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index adf0fcb..e7e657e 100644 --- a/crates/core_simd/src/masks/full_masks.rs diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index e06166d0ab7..1e47ccbd49f 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -84,6 +84,30 @@ fn simd_for_each_lane<'tcx>( } } +fn simd_pair_for_each_lane_typed<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, + x: CValue<'tcx>, + y: CValue<'tcx>, + ret: CPlace<'tcx>, + f: &dyn Fn(&mut FunctionCx<'_, '_, 'tcx>, CValue<'tcx>, CValue<'tcx>) -> CValue<'tcx>, +) { + assert_eq!(x.layout(), y.layout()); + let layout = x.layout(); + + let (lane_count, _lane_ty) = layout.ty.simd_size_and_type(fx.tcx); + let (ret_lane_count, _ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx); + assert_eq!(lane_count, ret_lane_count); + + for lane_idx in 0..lane_count { + let x_lane = x.value_lane(fx, lane_idx); + let y_lane = y.value_lane(fx, lane_idx); + + let res_lane = f(fx, x_lane, y_lane); + + ret.place_lane(fx, lane_idx).write_cvalue(fx, res_lane); + } +} + fn simd_pair_for_each_lane<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, x: CValue<'tcx>, diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 4d77370dfc5..a70ced7472f 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -730,9 +730,22 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( ret.write_cvalue(fx, res); } + sym::simd_saturating_add | sym::simd_saturating_sub => { + intrinsic_args!(fx, args => (x, y); intrinsic); + + let bin_op = match intrinsic { + sym::simd_saturating_add => BinOp::Add, + sym::simd_saturating_sub => BinOp::Sub, + _ => unreachable!(), + }; + + // FIXME use vector instructions when possible + simd_pair_for_each_lane_typed(fx, x, y, ret, &|fx, x_lane, y_lane| { + crate::num::codegen_saturating_int_binop(fx, bin_op, x_lane, y_lane) + }); + } + // simd_arith_offset - // simd_saturating_add - // simd_saturating_sub // simd_scatter // simd_gather // simd_select_bitmask |
