Skip to content

Commit 1f70802

Browse files
authored
Merge pull request rust-lang#1189 from bjorn3/stdsimd_fixes
Improve stdsimd support
2 parents 3563608 + 581e38b commit 1f70802

File tree

6 files changed

+453
-41
lines changed

6 files changed

+453
-41
lines changed

build_system/prepare.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ pub(crate) fn prepare() {
2727
"341f207c1071f7290e3f228c710817c280c8dca1",
2828
);
2929

30+
clone_repo(
31+
"stdsimd",
32+
"https://github.com/rust-lang/stdsimd",
33+
"be96995d8ddec03fac9a0caf4d4c51c7fbc33507",
34+
);
35+
apply_patches("stdsimd", Path::new("stdsimd"));
36+
3037
clone_repo(
3138
"simple-raytracer",
3239
"https://github.com/ebobby/simple-raytracer",
@@ -60,11 +67,7 @@ fn prepare_sysroot() {
6067
copy_dir_recursively(&sysroot_src_orig.join("library"), &sysroot_src.join("library"));
6168

6269
let rustc_version = get_rustc_version();
63-
fs::write(
64-
Path::new("build_sysroot").join("rustc_version"),
65-
&rustc_version,
66-
)
67-
.unwrap();
70+
fs::write(Path::new("build_sysroot").join("rustc_version"), &rustc_version).unwrap();
6871

6972
eprintln!("[GIT] init");
7073
let mut git_init_cmd = Command::new("git");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
From 6bfce5dc2cbf834c74dbccb7538adc08c6eb57e7 Mon Sep 17 00:00:00 2001
2+
From: bjorn3 <bjorn3@users.noreply.github.com>
3+
Date: Sun, 25 Jul 2021 18:39:31 +0200
4+
Subject: [PATCH] Disable unsupported tests
5+
6+
---
7+
crates/core_simd/src/array.rs | 2 ++
8+
crates/core_simd/src/lib.rs | 2 +-
9+
crates/core_simd/src/math.rs | 4 ++++
10+
crates/core_simd/tests/masks.rs | 12 ------------
11+
crates/core_simd/tests/ops_macros.rs | 6 ++++++
12+
crates/core_simd/tests/round.rs | 2 ++
13+
6 files changed, 15 insertions(+), 13 deletions(-)
14+
15+
diff --git a/crates/core_simd/src/array.rs b/crates/core_simd/src/array.rs
16+
index 25c5309..2b3d819 100644
17+
--- a/crates/core_simd/src/array.rs
18+
+++ b/crates/core_simd/src/array.rs
19+
@@ -22,6 +22,7 @@ where
20+
#[must_use]
21+
fn splat(val: Self::Scalar) -> Self;
22+
23+
+ /*
24+
/// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
25+
/// If an index is out of bounds, that lane instead selects the value from the "or" vector.
26+
/// ```
27+
@@ -150,6 +151,7 @@ where
28+
// Cleared ☢️ *mut T Zone
29+
}
30+
}
31+
+ */
32+
}
33+
34+
macro_rules! impl_simdarray_for {
35+
diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs
36+
index a64904d..299eb11 100644
37+
--- a/crates/core_simd/src/lib.rs
38+
+++ b/crates/core_simd/src/lib.rs
39+
@@ -1,7 +1,7 @@
40+
#![no_std]
41+
#![allow(incomplete_features)]
42+
#![feature(
43+
- const_generics,
44+
+ const_generics,
45+
platform_intrinsics,
46+
repr_simd,
47+
simd_ffi,
48+
diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs
49+
index 7290a28..e394730 100644
50+
--- a/crates/core_simd/src/math.rs
51+
+++ b/crates/core_simd/src/math.rs
52+
@@ -2,6 +2,7 @@ macro_rules! impl_uint_arith {
53+
($(($name:ident, $n:ident)),+) => {
54+
$( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {
55+
56+
+ /*
57+
/// Lanewise saturating add.
58+
///
59+
/// # Examples
60+
@@ -38,6 +39,7 @@ macro_rules! impl_uint_arith {
61+
pub fn saturating_sub(self, second: Self) -> Self {
62+
unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
63+
}
64+
+ */
65+
})+
66+
}
67+
}
68+
@@ -46,6 +48,7 @@ macro_rules! impl_int_arith {
69+
($(($name:ident, $n:ident)),+) => {
70+
$( impl<const LANES: usize> $name<LANES> where Self: crate::LanesAtMost32 {
71+
72+
+ /*
73+
/// Lanewise saturating add.
74+
///
75+
/// # Examples
76+
@@ -141,6 +144,7 @@ macro_rules! impl_int_arith {
77+
pub fn saturating_neg(self) -> Self {
78+
Self::splat(0).saturating_sub(self)
79+
}
80+
+ */
81+
})+
82+
}
83+
}
84+
diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs
85+
index 61d8e44..2bccae2 100644
86+
--- a/crates/core_simd/tests/masks.rs
87+
+++ b/crates/core_simd/tests/masks.rs
88+
@@ -67,18 +67,6 @@ macro_rules! test_mask_api {
89+
assert_eq!(int.to_array(), [-1, 0, 0, -1, 0, 0, -1, 0]);
90+
assert_eq!(core_simd::$name::<8>::from_int(int), mask);
91+
}
92+
-
93+
- #[test]
94+
- fn roundtrip_bitmask_conversion() {
95+
- let values = [
96+
- true, false, false, true, false, false, true, false,
97+
- true, true, false, false, false, false, false, true,
98+
- ];
99+
- let mask = core_simd::$name::<16>::from_array(values);
100+
- let bitmask = mask.to_bitmask();
101+
- assert_eq!(bitmask, [0b01001001, 0b10000011]);
102+
- assert_eq!(core_simd::$name::<16>::from_bitmask(bitmask), mask);
103+
- }
104+
}
105+
}
106+
}
107+
diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs
108+
index cb39e73..fc0ebe1 100644
109+
--- a/crates/core_simd/tests/ops_macros.rs
110+
+++ b/crates/core_simd/tests/ops_macros.rs
111+
@@ -435,6 +435,7 @@ macro_rules! impl_float_tests {
112+
)
113+
}
114+
115+
+ /*
116+
fn mul_add<const LANES: usize>() {
117+
test_helpers::test_ternary_elementwise(
118+
&Vector::<LANES>::mul_add,
119+
@@ -442,6 +443,7 @@ macro_rules! impl_float_tests {
120+
&|_, _, _| true,
121+
)
122+
}
123+
+ */
124+
125+
fn sqrt<const LANES: usize>() {
126+
test_helpers::test_unary_elementwise(
127+
@@ -491,6 +493,7 @@ macro_rules! impl_float_tests {
128+
)
129+
}
130+
131+
+ /*
132+
fn min<const LANES: usize>() {
133+
// Regular conditions (both values aren't zero)
134+
test_helpers::test_binary_elementwise(
135+
@@ -536,6 +539,7 @@ macro_rules! impl_float_tests {
136+
assert!(p_zero.max(n_zero).to_array().iter().all(|x| *x == 0.));
137+
assert!(n_zero.max(p_zero).to_array().iter().all(|x| *x == 0.));
138+
}
139+
+ */
140+
141+
fn clamp<const LANES: usize>() {
142+
test_helpers::test_3(&|value: [Scalar; LANES], mut min: [Scalar; LANES], mut max: [Scalar; LANES]| {
143+
@@ -581,6 +585,7 @@ macro_rules! impl_float_tests {
144+
});
145+
}
146+
147+
+ /*
148+
fn horizontal_max<const LANES: usize>() {
149+
test_helpers::test_1(&|x| {
150+
let vmax = Vector::<LANES>::from_array(x).horizontal_max();
151+
@@ -604,6 +609,7 @@ macro_rules! impl_float_tests {
152+
Ok(())
153+
});
154+
}
155+
+ */
156+
}
157+
}
158+
}
159+
diff --git a/crates/core_simd/tests/round.rs b/crates/core_simd/tests/round.rs
160+
index 37044a7..4cdc6b7 100644
161+
--- a/crates/core_simd/tests/round.rs
162+
+++ b/crates/core_simd/tests/round.rs
163+
@@ -25,6 +25,7 @@ macro_rules! float_rounding_test {
164+
)
165+
}
166+
167+
+ /*
168+
fn round<const LANES: usize>() {
169+
test_helpers::test_unary_elementwise(
170+
&Vector::<LANES>::round,
171+
@@ -32,6 +33,7 @@ macro_rules! float_rounding_test {
172+
&|_| true,
173+
)
174+
}
175+
+ */
176+
177+
fn trunc<const LANES: usize>() {
178+
test_helpers::test_unary_elementwise(
179+
--
180+
2.26.2.7.g19db9cfb68
181+

scripts/tests.sh

+8
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ function extended_sysroot_tests() {
136136
../build/cargo build --tests --target $TARGET_TRIPLE
137137
fi
138138
popd
139+
140+
pushd stdsimd
141+
echo "[TEST] rust-lang/stdsimd"
142+
../build/cargo build --all-targets --target $TARGET_TRIPLE
143+
if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
144+
../build/cargo test -q
145+
fi
146+
popd
139147
}
140148

141149
case "$1" in

src/intrinsics/mod.rs

+24-16
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,11 @@ fn simd_for_each_lane<'tcx>(
175175
assert_eq!(lane_count, ret_lane_count);
176176

177177
for lane_idx in 0..lane_count {
178-
let lane_idx = mir::Field::new(lane_idx.try_into().unwrap());
179-
let lane = val.value_field(fx, lane_idx).load_scalar(fx);
178+
let lane = val.value_lane(fx, lane_idx).load_scalar(fx);
180179

181180
let res_lane = f(fx, lane_layout, ret_lane_layout, lane);
182181

183-
ret.place_field(fx, lane_idx).write_cvalue(fx, res_lane);
182+
ret.place_lane(fx, lane_idx).write_cvalue(fx, res_lane);
184183
}
185184
}
186185

@@ -206,37 +205,38 @@ fn simd_pair_for_each_lane<'tcx>(
206205
let ret_lane_layout = fx.layout_of(ret_lane_ty);
207206
assert_eq!(lane_count, ret_lane_count);
208207

209-
for lane in 0..lane_count {
210-
let lane = mir::Field::new(lane.try_into().unwrap());
211-
let x_lane = x.value_field(fx, lane).load_scalar(fx);
212-
let y_lane = y.value_field(fx, lane).load_scalar(fx);
208+
for lane_idx in 0..lane_count {
209+
let x_lane = x.value_lane(fx, lane_idx).load_scalar(fx);
210+
let y_lane = y.value_lane(fx, lane_idx).load_scalar(fx);
213211

214212
let res_lane = f(fx, lane_layout, ret_lane_layout, x_lane, y_lane);
215213

216-
ret.place_field(fx, lane).write_cvalue(fx, res_lane);
214+
ret.place_lane(fx, lane_idx).write_cvalue(fx, res_lane);
217215
}
218216
}
219217

220218
fn simd_reduce<'tcx>(
221219
fx: &mut FunctionCx<'_, '_, 'tcx>,
222220
val: CValue<'tcx>,
221+
acc: Option<Value>,
223222
ret: CPlace<'tcx>,
224223
f: impl Fn(&mut FunctionCx<'_, '_, 'tcx>, TyAndLayout<'tcx>, Value, Value) -> Value,
225224
) {
226225
let (lane_count, lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx);
227226
let lane_layout = fx.layout_of(lane_ty);
228227
assert_eq!(lane_layout, ret.layout());
229228

230-
let mut res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx);
231-
for lane_idx in 1..lane_count {
232-
let lane =
233-
val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx);
229+
let (mut res_val, start_lane) =
230+
if let Some(acc) = acc { (acc, 0) } else { (val.value_lane(fx, 0).load_scalar(fx), 1) };
231+
for lane_idx in start_lane..lane_count {
232+
let lane = val.value_lane(fx, lane_idx).load_scalar(fx);
234233
res_val = f(fx, lane_layout, res_val, lane);
235234
}
236235
let res = CValue::by_val(res_val, lane_layout);
237236
ret.write_cvalue(fx, res);
238237
}
239238

239+
// FIXME move all uses to `simd_reduce`
240240
fn simd_reduce_bool<'tcx>(
241241
fx: &mut FunctionCx<'_, '_, 'tcx>,
242242
val: CValue<'tcx>,
@@ -246,14 +246,18 @@ fn simd_reduce_bool<'tcx>(
246246
let (lane_count, _lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx);
247247
assert!(ret.layout().ty.is_bool());
248248

249-
let res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx);
249+
let res_val = val.value_lane(fx, 0).load_scalar(fx);
250250
let mut res_val = fx.bcx.ins().band_imm(res_val, 1); // mask to boolean
251251
for lane_idx in 1..lane_count {
252-
let lane =
253-
val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx);
252+
let lane = val.value_lane(fx, lane_idx).load_scalar(fx);
254253
let lane = fx.bcx.ins().band_imm(lane, 1); // mask to boolean
255254
res_val = f(fx, res_val, lane);
256255
}
256+
let res_val = if fx.bcx.func.dfg.value_type(res_val) != types::I8 {
257+
fx.bcx.ins().ireduce(types::I8, res_val)
258+
} else {
259+
res_val
260+
};
257261
let res = CValue::by_val(res_val, ret.layout());
258262
ret.write_cvalue(fx, res);
259263
}
@@ -288,7 +292,11 @@ macro simd_cmp {
288292
if let Some(vector_ty) = vector_ty {
289293
let x = $x.load_scalar($fx);
290294
let y = $y.load_scalar($fx);
291-
let val = $fx.bcx.ins().icmp(IntCC::$cc, x, y);
295+
let val = if vector_ty.lane_type().is_float() {
296+
$fx.bcx.ins().fcmp(FloatCC::$cc_f, x, y)
297+
} else {
298+
$fx.bcx.ins().icmp(IntCC::$cc, x, y)
299+
};
292300

293301
// HACK This depends on the fact that icmp for vectors represents bools as 0 and !0, not 0 and 1.
294302
let val = $fx.bcx.ins().raw_bitcast(vector_ty, val);

0 commit comments

Comments
 (0)