Auto merge of #2007 - RalfJung:simd_saturating, r=RalfJung

implement simd_saturating intrinsics
This commit is contained in:
bors 2022-03-07 19:13:41 +00:00
commit ccaf7206e1
3 changed files with 28 additions and 3 deletions

View File

@ -1 +1 @@
297273c45b205820a4c055082c71677197a40b55
d137c3a7bd3b180317044f8ccb9a8b4b3bb07db3

View File

@ -372,7 +372,9 @@ enum Op {
| "simd_gt"
| "simd_ge"
| "simd_fmax"
| "simd_fmin" => {
| "simd_fmin"
| "simd_saturating_add"
| "simd_saturating_sub" => {
use mir::BinOp;
let &[ref left, ref right] = check_arg_count(args)?;
@ -385,6 +387,7 @@ enum Op {
enum Op {
MirOp(BinOp),
SaturatingOp(BinOp),
FMax,
FMin,
}
@ -407,6 +410,8 @@ enum Op {
"simd_ge" => Op::MirOp(BinOp::Ge),
"simd_fmax" => Op::FMax,
"simd_fmin" => Op::FMin,
"simd_saturating_add" => Op::SaturatingOp(BinOp::Add),
"simd_saturating_sub" => Op::SaturatingOp(BinOp::Sub),
_ => unreachable!(),
};
@ -442,6 +447,9 @@ enum Op {
Op::FMin => {
fmin_op(&left, &right)?
}
Op::SaturatingOp(mir_op) => {
this.saturating_arith(mir_op, &left, &right)?
}
};
this.write_scalar(val, &dest.into())?;
}

View File

@ -102,10 +102,27 @@ fn simd_ops_i32() {
assert_eq!(a % b, i32x4::from_array([0, 0, 1, 2]));
assert_eq!(i32x2::splat(i32::MIN) % i32x2::splat(-1), i32x2::splat(0));
assert_eq!(b.abs(), i32x4::from_array([1, 2, 3, 4]));
// FIXME not a per-lane method (https://github.com/rust-lang/rust/issues/94682)
// FIXME not a per-lane method (https://github.com/rust-lang/portable-simd/issues/247)
// assert_eq!(a.max(b * i32x4::splat(4)), i32x4::from_array([10, 10, 12, 10]));
// assert_eq!(a.min(b * i32x4::splat(4)), i32x4::from_array([4, 8, 10, -16]));
assert_eq!(
i8x4::from_array([i8::MAX, -23, 23, i8::MIN]).saturating_add(i8x4::from_array([1, i8::MIN, i8::MAX, 28])),
i8x4::from_array([i8::MAX, i8::MIN, i8::MAX, -100])
);
assert_eq!(
i8x4::from_array([i8::MAX, -28, 27, 42]).saturating_sub(i8x4::from_array([1, i8::MAX, i8::MAX, -80])),
i8x4::from_array([126, i8::MIN, -100, 122])
);
assert_eq!(
u8x4::from_array([u8::MAX, 0, 23, 42]).saturating_add(u8x4::from_array([1, 1, u8::MAX, 200])),
u8x4::from_array([u8::MAX, 1, u8::MAX, 242])
);
assert_eq!(
u8x4::from_array([u8::MAX, 0, 23, 42]).saturating_sub(u8x4::from_array([1, 1, u8::MAX, 200])),
u8x4::from_array([254, 0, 0, 0])
);
assert_eq!(!b, i32x4::from_array([!1, !2, !3, !-4]));
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]));