rust/tests/run-pass/portable-simd.rs

215 lines
8.6 KiB
Rust
Raw Normal View History

2022-02-21 20:41:52 -06:00
#![feature(portable_simd, platform_intrinsics)]
2021-11-18 08:36:01 -06:00
use std::simd::*;
fn simd_ops_f32() {
2021-11-18 08:36:01 -06:00
let a = f32x4::splat(10.0);
2022-03-03 13:54:54 -06:00
let b = f32x4::from_array([1.0, 2.0, 3.0, -4.0]);
assert_eq!(-b, f32x4::from_array([-1.0, -2.0, -3.0, 4.0]));
assert_eq!(a + b, f32x4::from_array([11.0, 12.0, 13.0, 6.0]));
assert_eq!(a - b, f32x4::from_array([9.0, 8.0, 7.0, 14.0]));
assert_eq!(a * b, f32x4::from_array([10.0, 20.0, 30.0, -40.0]));
assert_eq!(b / a, f32x4::from_array([0.1, 0.2, 0.3, -0.4]));
2021-12-08 09:01:51 -06:00
assert_eq!(a / f32x4::splat(2.0), f32x4::splat(5.0));
assert_eq!(a % b, f32x4::from_array([0.0, 0.0, 1.0, 2.0]));
2022-03-03 13:54:54 -06:00
assert_eq!(b.abs(), f32x4::from_array([1.0, 2.0, 3.0, 4.0]));
2022-03-06 12:58:41 -06:00
assert_eq!(a.lanes_eq(f32x4::splat(5.0) * b), Mask::from_array([false, true, false, false]));
assert_eq!(a.lanes_ne(f32x4::splat(5.0) * b), Mask::from_array([true, false, true, true]));
assert_eq!(a.lanes_le(f32x4::splat(5.0) * b), Mask::from_array([false, true, true, false]));
assert_eq!(a.lanes_lt(f32x4::splat(5.0) * b), Mask::from_array([false, false, true, false]));
assert_eq!(a.lanes_ge(f32x4::splat(5.0) * b), Mask::from_array([true, true, false, true]));
assert_eq!(a.lanes_gt(f32x4::splat(5.0) * b), Mask::from_array([true, false, false, true]));
2022-03-05 22:03:14 -06:00
assert_eq!(a.horizontal_sum(), 40.0);
assert_eq!(b.horizontal_sum(), 2.0);
2022-03-06 12:58:41 -06:00
assert_eq!(a.horizontal_product(), 100.0 * 100.0);
2022-03-05 22:03:14 -06:00
assert_eq!(b.horizontal_product(), -24.0);
2022-03-03 13:54:54 -06:00
}
fn simd_ops_f64() {
let a = f64x4::splat(10.0);
let b = f64x4::from_array([1.0, 2.0, 3.0, -4.0]);
assert_eq!(-b, f64x4::from_array([-1.0, -2.0, -3.0, 4.0]));
assert_eq!(a + b, f64x4::from_array([11.0, 12.0, 13.0, 6.0]));
assert_eq!(a - b, f64x4::from_array([9.0, 8.0, 7.0, 14.0]));
assert_eq!(a * b, f64x4::from_array([10.0, 20.0, 30.0, -40.0]));
assert_eq!(b / a, f64x4::from_array([0.1, 0.2, 0.3, -0.4]));
assert_eq!(a / f64x4::splat(2.0), f64x4::splat(5.0));
assert_eq!(a % b, f64x4::from_array([0.0, 0.0, 1.0, 2.0]));
assert_eq!(b.abs(), f64x4::from_array([1.0, 2.0, 3.0, 4.0]));
2022-03-06 12:58:41 -06:00
assert_eq!(a.lanes_eq(f64x4::splat(5.0) * b), Mask::from_array([false, true, false, false]));
assert_eq!(a.lanes_ne(f64x4::splat(5.0) * b), Mask::from_array([true, false, true, true]));
assert_eq!(a.lanes_le(f64x4::splat(5.0) * b), Mask::from_array([false, true, true, false]));
assert_eq!(a.lanes_lt(f64x4::splat(5.0) * b), Mask::from_array([false, false, true, false]));
assert_eq!(a.lanes_ge(f64x4::splat(5.0) * b), Mask::from_array([true, true, false, true]));
assert_eq!(a.lanes_gt(f64x4::splat(5.0) * b), Mask::from_array([true, false, false, true]));
2022-03-05 22:03:14 -06:00
assert_eq!(a.horizontal_sum(), 40.0);
assert_eq!(b.horizontal_sum(), 2.0);
2022-03-06 12:58:41 -06:00
assert_eq!(a.horizontal_product(), 100.0 * 100.0);
2022-03-05 22:03:14 -06:00
assert_eq!(b.horizontal_product(), -24.0);
}
fn simd_ops_i32() {
let a = i32x4::splat(10);
let b = i32x4::from_array([1, 2, 3, -4]);
assert_eq!(-b, i32x4::from_array([-1, -2, -3, 4]));
assert_eq!(a + b, i32x4::from_array([11, 12, 13, 6]));
assert_eq!(a - b, i32x4::from_array([9, 8, 7, 14]));
assert_eq!(a * b, i32x4::from_array([10, 20, 30, -40]));
assert_eq!(a / b, i32x4::from_array([10, 5, 3, -2]));
2022-02-21 20:41:52 -06:00
assert_eq!(a / i32x4::splat(2), i32x4::splat(5));
2022-03-01 17:44:37 -06:00
assert_eq!(i32x2::splat(i32::MIN) / i32x2::splat(-1), i32x2::splat(i32::MIN));
2022-02-21 20:41:52 -06:00
assert_eq!(a % b, i32x4::from_array([0, 0, 1, 2]));
2022-03-01 17:44:37 -06:00
assert_eq!(i32x2::splat(i32::MIN) % i32x2::splat(-1), i32x2::splat(0));
assert_eq!(b << i32x4::splat(2), i32x4::from_array([4, 8, 12, -16]));
assert_eq!(b >> i32x4::splat(1), i32x4::from_array([0, 1, 1, -2]));
2022-02-04 10:55:53 -06:00
assert_eq!(b & i32x4::splat(2), i32x4::from_array([0, 2, 2, 0]));
assert_eq!(b | i32x4::splat(2), i32x4::from_array([3, 2, 3, -2]));
assert_eq!(b ^ i32x4::splat(2), i32x4::from_array([3, 0, 1, -2]));
2022-03-06 12:58:41 -06:00
assert_eq!(a.lanes_eq(i32x4::splat(5) * b), Mask::from_array([false, true, false, false]));
assert_eq!(a.lanes_ne(i32x4::splat(5) * b), Mask::from_array([true, false, true, true]));
assert_eq!(a.lanes_le(i32x4::splat(5) * b), Mask::from_array([false, true, true, false]));
assert_eq!(a.lanes_lt(i32x4::splat(5) * b), Mask::from_array([false, false, true, false]));
assert_eq!(a.lanes_ge(i32x4::splat(5) * b), Mask::from_array([true, true, false, true]));
assert_eq!(a.lanes_gt(i32x4::splat(5) * b), Mask::from_array([true, false, false, true]));
assert_eq!(a.horizontal_and(), 10);
assert_eq!(b.horizontal_and(), 0);
assert_eq!(a.horizontal_or(), 10);
assert_eq!(b.horizontal_or(), -1);
assert_eq!(a.horizontal_xor(), 0);
assert_eq!(b.horizontal_xor(), -4);
2022-03-05 18:02:00 -06:00
assert_eq!(a.horizontal_sum(), 40);
assert_eq!(b.horizontal_sum(), 2);
2022-03-06 12:58:41 -06:00
assert_eq!(a.horizontal_product(), 100 * 100);
2022-03-05 22:03:14 -06:00
assert_eq!(b.horizontal_product(), -24);
}
2022-03-06 12:58:41 -06:00
fn simd_mask() {
let intmask = Mask::from_int(i32x4::from_array([0, -1, 0, 0]));
assert_eq!(intmask, Mask::from_array([false, true, false, false]));
assert_eq!(intmask.to_array(), [false, true, false, false]);
}
fn simd_cast() {
// between integer types
assert_eq!(i32x4::from_array([1, 2, 3, -4]), i16x4::from_array([1, 2, 3, -4]).cast());
assert_eq!(i16x4::from_array([1, 2, 3, -4]), i32x4::from_array([1, 2, 3, -4]).cast());
assert_eq!(i32x4::from_array([1, -1, 3, 4]), u64x4::from_array([1, u64::MAX, 3, 4]).cast());
// float -> int
assert_eq!(
i8x4::from_array([127, -128, 127, -128]),
f32x4::from_array([127.99, -128.99, 999.0, -999.0]).cast()
);
assert_eq!(
i32x4::from_array([0, 1, -1, 2147483520]),
f32x4::from_array([
-0.0,
/*0x1.19999ap+0*/ f32::from_bits(0x3f8ccccd),
/*-0x1.19999ap+0*/ f32::from_bits(0xbf8ccccd),
2147483520.0
])
.cast()
);
assert_eq!(
i32x8::from_array([i32::MAX, i32::MIN, i32::MAX, i32::MIN, i32::MAX, i32::MIN, 0, 0]),
f32x8::from_array([
2147483648.0f32,
-2147483904.0f32,
f32::MAX,
f32::MIN,
f32::INFINITY,
f32::NEG_INFINITY,
f32::NAN,
-f32::NAN,
])
.cast()
);
// int -> float
assert_eq!(
f32x4::from_array([
-2147483648.0,
/*0x1.26580cp+30*/ f32::from_bits(0x4e932c06),
16777220.0,
-16777220.0,
]),
i32x4::from_array([-2147483647i32, 1234567890i32, 16777219i32, -16777219i32]).cast()
);
// float -> float
assert_eq!(
f32x4::from_array([f32::INFINITY, f32::INFINITY, f32::NEG_INFINITY, f32::NEG_INFINITY]),
f64x4::from_array([f64::MAX, f64::INFINITY, f64::MIN, f64::NEG_INFINITY]).cast()
);
// unchecked casts
unsafe {
assert_eq!(
i32x4::from_array([0, 1, -1, 2147483520]),
f32x4::from_array([
-0.0,
/*0x1.19999ap+0*/ f32::from_bits(0x3f8ccccd),
/*-0x1.19999ap+0*/ f32::from_bits(0xbf8ccccd),
2147483520.0
])
.to_int_unchecked()
);
assert_eq!(
u64x4::from_array([0, 10000000000000000, u64::MAX - 2047, 9223372036854775808]),
f64x4::from_array([
-0.99999999999,
1e16,
(u64::MAX - 1024) as f64,
9223372036854775808.0
])
.to_int_unchecked()
);
}
}
2022-02-21 20:41:52 -06:00
fn simd_intrinsics() {
extern "platform-intrinsic" {
2022-03-01 17:40:40 -06:00
fn simd_eq<T, U>(x: T, y: T) -> U;
fn simd_reduce_any<T>(x: T) -> bool;
fn simd_reduce_all<T>(x: T) -> bool;
2022-03-01 17:40:40 -06:00
fn simd_select<M, T>(m: M, yes: T, no: T) -> T;
2022-02-21 20:41:52 -06:00
}
unsafe {
2022-03-01 17:40:40 -06:00
// Make sure simd_eq returns all-1 for `true`
let a = i32x4::splat(10);
let b = i32x4::from_array([1, 2, 10, 4]);
let c: i32x4 = simd_eq(a, b);
assert_eq!(c, i32x4::from_array([0, 0, -1, 0]));
2022-02-21 20:41:52 -06:00
assert!(!simd_reduce_any(i32x4::splat(0)));
assert!(simd_reduce_any(i32x4::splat(-1)));
assert!(simd_reduce_any(i32x2::from_array([0, -1])));
assert!(!simd_reduce_all(i32x4::splat(0)));
assert!(simd_reduce_all(i32x4::splat(-1)));
assert!(!simd_reduce_all(i32x2::from_array([0, -1])));
2022-03-01 17:40:40 -06:00
2022-03-06 12:58:41 -06:00
assert_eq!(
simd_select(i8x4::from_array([0, -1, -1, 0]), a, b),
i32x4::from_array([1, 10, 10, 4])
);
assert_eq!(
simd_select(i8x4::from_array([0, -1, -1, 0]), b, a),
i32x4::from_array([10, 2, 10, 10])
);
2022-02-21 20:41:52 -06:00
}
}
fn main() {
2022-03-06 12:58:41 -06:00
simd_mask();
simd_ops_f32();
2022-03-03 13:54:54 -06:00
simd_ops_f64();
simd_ops_i32();
2022-03-06 12:58:41 -06:00
simd_cast();
2022-02-21 20:41:52 -06:00
simd_intrinsics();
2021-11-18 08:36:01 -06:00
}