diff --git a/rust-version b/rust-version index a769188204f..dcc365ef0ad 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -297273c45b205820a4c055082c71677197a40b55 +d137c3a7bd3b180317044f8ccb9a8b4b3bb07db3 diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index 897ebe4ae79..49c9c0fb0d9 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -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())?; } diff --git a/tests/run-pass/portable-simd.rs b/tests/run-pass/portable-simd.rs index 48297ee4e69..b87bd4fd6ad 100644 --- a/tests/run-pass/portable-simd.rs +++ b/tests/run-pass/portable-simd.rs @@ -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]));