Skip to content

Commit fa76604

Browse files
authored
Merge pull request rust-lang#1277 from bjorn3/simd_improvements
Implement a couple of portable simd intrinsics
2 parents c4c393c + 13fcf47 commit fa76604

File tree

5 files changed

+190
-218
lines changed

5 files changed

+190
-218
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,16 @@
1-
From 82f597cf81b169b0e72a576ac8751f598c059c48 Mon Sep 17 00:00:00 2001
1+
From b742f03694b920cc14400727d54424e8e1b60928 Mon Sep 17 00:00:00 2001
22
From: bjorn3 <[email protected]>
33
Date: Thu, 18 Nov 2021 19:28:40 +0100
44
Subject: [PATCH] Disable unsupported tests
55

66
---
77
crates/core_simd/src/elements/int.rs | 8 ++++++++
88
crates/core_simd/src/elements/uint.rs | 4 ++++
9-
crates/core_simd/src/masks/full_masks.rs | 9 +++++++++
9+
crates/core_simd/src/masks/full_masks.rs | 6 ++++++
1010
crates/core_simd/src/vector.rs | 2 ++
11-
crates/core_simd/tests/masks.rs | 2 ++
12-
5 files changed, 25 insertions(+)
11+
crates/core_simd/tests/masks.rs | 3 ---
12+
5 files changed, 20 insertions(+), 3 deletions(-)
1313

14-
diff --git a/crates/core_simd/src/elements/int.rs b/crates/core_simd/src/elements/int.rs
15-
index 9b8c37e..ea95f08 100644
16-
--- a/crates/core_simd/src/elements/int.rs
17-
+++ b/crates/core_simd/src/elements/int.rs
18-
@@ -11,6 +11,7 @@ pub trait SimdInt: Copy + Sealed {
19-
/// Scalar type contained by this SIMD vector type.
20-
type Scalar;
21-
22-
+ /*
23-
/// Lanewise saturating add.
24-
///
25-
/// # Examples
26-
@@ -45,6 +46,7 @@ pub trait SimdInt: Copy + Sealed {
27-
/// assert_eq!(unsat, Simd::from_array([1, MAX, MIN, 0]));
28-
/// assert_eq!(sat, Simd::from_array([MIN, MIN, MIN, 0]));
29-
fn saturating_sub(self, second: Self) -> Self;
30-
+ */
31-
32-
/// Lanewise absolute value, implemented in Rust.
33-
/// Every lane becomes its absolute value.
34-
@@ -61,6 +63,7 @@ pub trait SimdInt: Copy + Sealed {
35-
/// ```
36-
fn abs(self) -> Self;
37-
38-
+ /*
39-
/// Lanewise saturating absolute value, implemented in Rust.
40-
/// As abs(), except the MIN value becomes MAX instead of itself.
41-
///
42-
@@ -96,6 +99,7 @@ pub trait SimdInt: Copy + Sealed {
43-
/// assert_eq!(sat, Simd::from_array([MAX, 2, -3, MIN + 1]));
44-
/// ```
45-
fn saturating_neg(self) -> Self;
46-
+ */
47-
48-
/// Returns true for each positive lane and false if it is zero or negative.
49-
fn is_positive(self) -> Self::Mask;
50-
@@ -199,6 +203,7 @@ macro_rules! impl_trait {
51-
type Mask = Mask<<$ty as SimdElement>::Mask, LANES>;
52-
type Scalar = $ty;
53-
54-
+ /*
55-
#[inline]
56-
fn saturating_add(self, second: Self) -> Self {
57-
// Safety: `self` is a vector
58-
@@ -210,6 +215,7 @@ macro_rules! impl_trait {
59-
// Safety: `self` is a vector
60-
unsafe { intrinsics::simd_saturating_sub(self, second) }
61-
}
62-
+ */
63-
64-
#[inline]
65-
fn abs(self) -> Self {
66-
@@ -218,6 +224,7 @@ macro_rules! impl_trait {
67-
(self^m) - m
68-
}
69-
70-
+ /*
71-
#[inline]
72-
fn saturating_abs(self) -> Self {
73-
// arith shift for -1 or 0 mask based on sign bit, giving 2s complement
74-
@@ -230,6 +237,7 @@ macro_rules! impl_trait {
75-
fn saturating_neg(self) -> Self {
76-
Self::splat(0).saturating_sub(self)
77-
}
78-
+ */
79-
80-
#[inline]
81-
fn is_positive(self) -> Self::Mask {
82-
diff --git a/crates/core_simd/src/elements/uint.rs b/crates/core_simd/src/elements/uint.rs
83-
index 21e7e76..0d6dee2 100644
84-
--- a/crates/core_simd/src/elements/uint.rs
85-
+++ b/crates/core_simd/src/elements/uint.rs
86-
@@ -6,6 +6,7 @@ pub trait SimdUint: Copy + Sealed {
87-
/// Scalar type contained by this SIMD vector type.
88-
type Scalar;
89-
90-
+ /*
91-
/// Lanewise saturating add.
92-
///
93-
/// # Examples
94-
@@ -40,6 +41,7 @@ pub trait SimdUint: Copy + Sealed {
95-
/// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0]));
96-
/// assert_eq!(sat, Simd::splat(0));
97-
fn saturating_sub(self, second: Self) -> Self;
98-
+ */
99-
100-
/// Returns the sum of the lanes of the vector, with wrapping addition.
101-
fn reduce_sum(self) -> Self::Scalar;
102-
@@ -78,6 +80,7 @@ macro_rules! impl_trait {
103-
{
104-
type Scalar = $ty;
105-
106-
+ /*
107-
#[inline]
108-
fn saturating_add(self, second: Self) -> Self {
109-
// Safety: `self` is a vector
110-
@@ -89,6 +92,7 @@ macro_rules! impl_trait {
111-
// Safety: `self` is a vector
112-
unsafe { intrinsics::simd_saturating_sub(self, second) }
113-
}
114-
+ */
115-
116-
#[inline]
117-
fn reduce_sum(self) -> Self::Scalar {
118-
diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs
119-
index adf0fcb..5b10292 100644
120-
--- a/crates/core_simd/src/masks/full_masks.rs
121-
+++ b/crates/core_simd/src/masks/full_masks.rs
122-
@@ -150,6 +150,7 @@ where
123-
super::Mask<T, LANES>: ToBitMaskArray,
124-
[(); <super::Mask<T, LANES> as ToBitMaskArray>::BYTES]: Sized,
125-
{
126-
+ /*
127-
assert_eq!(<super::Mask<T, LANES> as ToBitMaskArray>::BYTES, N);
128-
129-
// Safety: N is the correct bitmask size
130-
@@ -170,6 +171,8 @@ where
131-
132-
bitmask
133-
}
134-
+ */
135-
+ panic!();
136-
}
137-
138-
#[cfg(feature = "generic_const_exprs")]
139-
@@ -209,6 +212,7 @@ where
140-
where
141-
super::Mask<T, LANES>: ToBitMask<BitMask = U>,
142-
{
143-
+ /*
144-
// Safety: U is required to be the appropriate bitmask type
145-
let bitmask: U = unsafe { intrinsics::simd_bitmask(self.0) };
146-
147-
@@ -218,6 +222,8 @@ where
148-
} else {
149-
bitmask
150-
}
151-
+ */
152-
+ panic!();
153-
}
154-
155-
#[inline]
156-
@@ -225,6 +231,7 @@ where
157-
where
158-
super::Mask<T, LANES>: ToBitMask<BitMask = U>,
159-
{
160-
+ /*
161-
// LLVM assumes bit order should match endianness
162-
let bitmask = if cfg!(target_endian = "big") {
163-
bitmask.reverse_bits(LANES)
164-
@@ -240,6 +247,8 @@ where
165-
Self::splat(false).to_int(),
166-
))
167-
}
168-
+ */
169-
+ panic!();
170-
}
171-
172-
#[inline]
17314
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
17415
index e8e8f68..7173c24 100644
17516
--- a/crates/core_simd/src/vector.rs
@@ -190,25 +31,5 @@ index e8e8f68..7173c24 100644
19031
}
19132

19233
impl<T, const LANES: usize> Copy for Simd<T, LANES>
193-
diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs
194-
index 673d0db..0d68b01 100644
195-
--- a/crates/core_simd/tests/masks.rs
196-
+++ b/crates/core_simd/tests/masks.rs
197-
@@ -59,6 +59,7 @@ macro_rules! test_mask_api {
198-
assert!(!v.all());
199-
}
200-
201-
+ /*
202-
#[test]
203-
fn roundtrip_int_conversion() {
204-
let values = [true, false, false, true, false, false, true, false];
205-
@@ -99,6 +100,7 @@ macro_rules! test_mask_api {
206-
assert_eq!(bitmask, 0b01);
207-
assert_eq!(core_simd::Mask::<$type, 2>::from_bitmask(bitmask), mask);
208-
}
209-
+ */
210-
211-
#[test]
212-
fn cast() {
21334
--
21435
2.25.1

src/intrinsics/llvm.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
2929
let mut res = fx.bcx.ins().iconst(types::I32, 0);
3030

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

3534
// cast float to int
3635
let a_lane = match lane_ty {

src/intrinsics/mod.rs

+25-31
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,30 @@ fn simd_for_each_lane<'tcx>(
8484
}
8585
}
8686

87+
fn simd_pair_for_each_lane_typed<'tcx>(
88+
fx: &mut FunctionCx<'_, '_, 'tcx>,
89+
x: CValue<'tcx>,
90+
y: CValue<'tcx>,
91+
ret: CPlace<'tcx>,
92+
f: &dyn Fn(&mut FunctionCx<'_, '_, 'tcx>, CValue<'tcx>, CValue<'tcx>) -> CValue<'tcx>,
93+
) {
94+
assert_eq!(x.layout(), y.layout());
95+
let layout = x.layout();
96+
97+
let (lane_count, _lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
98+
let (ret_lane_count, _ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
99+
assert_eq!(lane_count, ret_lane_count);
100+
101+
for lane_idx in 0..lane_count {
102+
let x_lane = x.value_lane(fx, lane_idx);
103+
let y_lane = y.value_lane(fx, lane_idx);
104+
105+
let res_lane = f(fx, x_lane, y_lane);
106+
107+
ret.place_lane(fx, lane_idx).write_cvalue(fx, res_lane);
108+
}
109+
}
110+
87111
fn simd_pair_for_each_lane<'tcx>(
88112
fx: &mut FunctionCx<'_, '_, 'tcx>,
89113
x: CValue<'tcx>,
@@ -507,37 +531,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
507531
_ => unreachable!(),
508532
};
509533

510-
let signed = type_sign(lhs.layout().ty);
511-
512-
let checked_res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs);
513-
514-
let (val, has_overflow) = checked_res.load_scalar_pair(fx);
515-
let clif_ty = fx.clif_type(lhs.layout().ty).unwrap();
516-
517-
let (min, max) = type_min_max_value(&mut fx.bcx, clif_ty, signed);
518-
519-
let val = match (intrinsic, signed) {
520-
(sym::saturating_add, false) => fx.bcx.ins().select(has_overflow, max, val),
521-
(sym::saturating_sub, false) => fx.bcx.ins().select(has_overflow, min, val),
522-
(sym::saturating_add, true) => {
523-
let rhs = rhs.load_scalar(fx);
524-
let rhs_ge_zero =
525-
fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
526-
let sat_val = fx.bcx.ins().select(rhs_ge_zero, max, min);
527-
fx.bcx.ins().select(has_overflow, sat_val, val)
528-
}
529-
(sym::saturating_sub, true) => {
530-
let rhs = rhs.load_scalar(fx);
531-
let rhs_ge_zero =
532-
fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
533-
let sat_val = fx.bcx.ins().select(rhs_ge_zero, min, max);
534-
fx.bcx.ins().select(has_overflow, sat_val, val)
535-
}
536-
_ => unreachable!(),
537-
};
538-
539-
let res = CValue::by_val(val, lhs.layout());
540-
534+
let res = crate::num::codegen_saturating_int_binop(fx, bin_op, lhs, rhs);
541535
ret.write_cvalue(fx, res);
542536
}
543537
sym::rotate_left => {

0 commit comments

Comments
 (0)