Skip to content

Commit

Permalink
Merge pull request rust-lang#1277 from bjorn3/simd_improvements
Browse files Browse the repository at this point in the history
Implement a couple of portable simd intrinsics
  • Loading branch information
bjorn3 authored Sep 9, 2022
2 parents c4c393c + 13fcf47 commit fa76604
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 218 deletions.
187 changes: 4 additions & 183 deletions patches/0001-portable-simd-Disable-unsupported-tests.patch
Original file line number Diff line number Diff line change
@@ -1,175 +1,16 @@
From 82f597cf81b169b0e72a576ac8751f598c059c48 Mon Sep 17 00:00:00 2001
From b742f03694b920cc14400727d54424e8e1b60928 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 18 Nov 2021 19:28:40 +0100
Subject: [PATCH] Disable unsupported tests

---
crates/core_simd/src/elements/int.rs | 8 ++++++++
crates/core_simd/src/elements/uint.rs | 4 ++++
crates/core_simd/src/masks/full_masks.rs | 9 +++++++++
crates/core_simd/src/masks/full_masks.rs | 6 ++++++
crates/core_simd/src/vector.rs | 2 ++
crates/core_simd/tests/masks.rs | 2 ++
5 files changed, 25 insertions(+)
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..5b10292 100644
--- a/crates/core_simd/src/masks/full_masks.rs
+++ b/crates/core_simd/src/masks/full_masks.rs
@@ -150,6 +150,7 @@ 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
@@ -170,6 +171,8 @@ where

bitmask
}
+ */
+ panic!();
}

#[cfg(feature = "generic_const_exprs")]
@@ -209,6 +212,7 @@ where
where
super::Mask<T, LANES>: ToBitMask<BitMask = U>,
{
+ /*
// Safety: U is required to be the appropriate bitmask type
let bitmask: U = unsafe { intrinsics::simd_bitmask(self.0) };

@@ -218,6 +222,8 @@ where
} else {
bitmask
}
+ */
+ panic!();
}

#[inline]
@@ -225,6 +231,7 @@ where
where
super::Mask<T, LANES>: ToBitMask<BitMask = U>,
{
+ /*
// LLVM assumes bit order should match endianness
let bitmask = if cfg!(target_endian = "big") {
bitmask.reverse_bits(LANES)
@@ -240,6 +247,8 @@ where
Self::splat(false).to_int(),
))
}
+ */
+ panic!();
}

#[inline]
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
index e8e8f68..7173c24 100644
--- a/crates/core_simd/src/vector.rs
Expand All @@ -190,25 +31,5 @@ index e8e8f68..7173c24 100644
}

impl<T, const LANES: usize> Copy for Simd<T, LANES>
diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs
index 673d0db..0d68b01 100644
--- a/crates/core_simd/tests/masks.rs
+++ b/crates/core_simd/tests/masks.rs
@@ -59,6 +59,7 @@ macro_rules! test_mask_api {
assert!(!v.all());
}

+ /*
#[test]
fn roundtrip_int_conversion() {
let values = [true, false, false, true, false, false, true, false];
@@ -99,6 +100,7 @@ macro_rules! test_mask_api {
assert_eq!(bitmask, 0b01);
assert_eq!(core_simd::Mask::<$type, 2>::from_bitmask(bitmask), mask);
}
+ */

#[test]
fn cast() {
--
2.25.1
3 changes: 1 addition & 2 deletions src/intrinsics/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
let mut res = fx.bcx.ins().iconst(types::I32, 0);

for lane in (0..lane_count).rev() {
let a_lane =
a.value_field(fx, mir::Field::new(lane.try_into().unwrap())).load_scalar(fx);
let a_lane = a.value_lane(fx, lane).load_scalar(fx);

// cast float to int
let a_lane = match lane_ty {
Expand Down
56 changes: 25 additions & 31 deletions src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down Expand Up @@ -507,37 +531,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
_ => unreachable!(),
};

let signed = type_sign(lhs.layout().ty);

let checked_res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs);

let (val, has_overflow) = checked_res.load_scalar_pair(fx);
let clif_ty = fx.clif_type(lhs.layout().ty).unwrap();

let (min, max) = type_min_max_value(&mut fx.bcx, clif_ty, signed);

let val = match (intrinsic, signed) {
(sym::saturating_add, false) => fx.bcx.ins().select(has_overflow, max, val),
(sym::saturating_sub, false) => fx.bcx.ins().select(has_overflow, min, val),
(sym::saturating_add, true) => {
let rhs = rhs.load_scalar(fx);
let rhs_ge_zero =
fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
let sat_val = fx.bcx.ins().select(rhs_ge_zero, max, min);
fx.bcx.ins().select(has_overflow, sat_val, val)
}
(sym::saturating_sub, true) => {
let rhs = rhs.load_scalar(fx);
let rhs_ge_zero =
fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
let sat_val = fx.bcx.ins().select(rhs_ge_zero, min, max);
fx.bcx.ins().select(has_overflow, sat_val, val)
}
_ => unreachable!(),
};

let res = CValue::by_val(val, lhs.layout());

let res = crate::num::codegen_saturating_int_binop(fx, bin_op, lhs, rhs);
ret.write_cvalue(fx, res);
}
sym::rotate_left => {
Expand Down
Loading

0 comments on commit fa76604

Please sign in to comment.