From a534bbbf8aeb14d2ee1c2d167e6e6073a114bf69 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Nov 2021 17:13:16 -0500 Subject: [PATCH] portable SIMD: add rem intrinsic; test div and rem intrinsic UB --- src/shims/intrinsics.rs | 3 ++- .../{div-by-zero-1.rs => div-by-zero.rs} | 0 .../{div-by-zero-2.rs => rem-by-zero.rs} | 0 tests/compile-fail/intrinsics/simd-div-by-zero.rs | 15 +++++++++++++++ tests/compile-fail/intrinsics/simd-rem-by-zero.rs | 15 +++++++++++++++ tests/run-pass/portable-simd.rs | 2 ++ 6 files changed, 34 insertions(+), 1 deletion(-) rename tests/compile-fail/intrinsics/{div-by-zero-1.rs => div-by-zero.rs} (100%) rename tests/compile-fail/intrinsics/{div-by-zero-2.rs => rem-by-zero.rs} (100%) create mode 100644 tests/compile-fail/intrinsics/simd-div-by-zero.rs create mode 100644 tests/compile-fail/intrinsics/simd-rem-by-zero.rs diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index d684b41ed81d..547f23f620d2 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -306,7 +306,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } // SIMD operations - "simd_add" | "simd_sub" | "simd_mul" | "simd_div" => { + "simd_add" | "simd_sub" | "simd_mul" | "simd_div" | "simd_rem" => { let &[ref left, ref right] = check_arg_count(args)?; let (left, left_len) = this.operand_to_simd(left)?; let (right, right_len) = this.operand_to_simd(right)?; @@ -320,6 +320,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx "simd_sub" => mir::BinOp::Sub, "simd_mul" => mir::BinOp::Mul, "simd_div" => mir::BinOp::Div, + "simd_rem" => mir::BinOp::Rem, _ => unreachable!(), }; diff --git a/tests/compile-fail/intrinsics/div-by-zero-1.rs b/tests/compile-fail/intrinsics/div-by-zero.rs similarity index 100% rename from tests/compile-fail/intrinsics/div-by-zero-1.rs rename to tests/compile-fail/intrinsics/div-by-zero.rs diff --git a/tests/compile-fail/intrinsics/div-by-zero-2.rs b/tests/compile-fail/intrinsics/rem-by-zero.rs similarity index 100% rename from tests/compile-fail/intrinsics/div-by-zero-2.rs rename to tests/compile-fail/intrinsics/rem-by-zero.rs diff --git a/tests/compile-fail/intrinsics/simd-div-by-zero.rs b/tests/compile-fail/intrinsics/simd-div-by-zero.rs new file mode 100644 index 000000000000..4244e63d23e5 --- /dev/null +++ b/tests/compile-fail/intrinsics/simd-div-by-zero.rs @@ -0,0 +1,15 @@ +#![feature(platform_intrinsics, repr_simd)] + +extern "platform-intrinsic" { + pub(crate) fn simd_div(x: T, y: T) -> T; +} + +#[repr(simd)] +#[allow(non_camel_case_types)] +struct i32x2(i32, i32); + +fn main() { unsafe { + let x = i32x2(1, 1); + let y = i32x2(1, 0); + simd_div(x, y); //~ERROR Undefined Behavior: dividing by zero +} } diff --git a/tests/compile-fail/intrinsics/simd-rem-by-zero.rs b/tests/compile-fail/intrinsics/simd-rem-by-zero.rs new file mode 100644 index 000000000000..bc3128b5fb5f --- /dev/null +++ b/tests/compile-fail/intrinsics/simd-rem-by-zero.rs @@ -0,0 +1,15 @@ +#![feature(platform_intrinsics, repr_simd)] + +extern "platform-intrinsic" { + pub(crate) fn simd_rem(x: T, y: T) -> T; +} + +#[repr(simd)] +#[allow(non_camel_case_types)] +struct i32x2(i32, i32); + +fn main() { unsafe { + let x = i32x2(1, 1); + let y = i32x2(1, 0); + simd_rem(x, y); //~ERROR Undefined Behavior: calculating the remainder with a divisor of zero +} } diff --git a/tests/run-pass/portable-simd.rs b/tests/run-pass/portable-simd.rs index 42a6befd868b..2d94c87ff042 100644 --- a/tests/run-pass/portable-simd.rs +++ b/tests/run-pass/portable-simd.rs @@ -9,6 +9,7 @@ fn simd_ops_f32() { 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])); assert_eq!(a / 2.0, f32x4::splat(5.0)); + assert_eq!(a % b, f32x4::from_array([0.0, 0.0, 1.0, 2.0])); } fn simd_ops_i32() { @@ -19,6 +20,7 @@ fn simd_ops_i32() { assert_eq!(a * b, i32x4::from_array([10, 20, 30, 40])); assert_eq!(a / b, i32x4::from_array([10, 5, 3, 2])); assert_eq!(a / 2, i32x4::splat(5)); + assert_eq!(a % b, i32x4::from_array([0, 0, 1, 2])); } fn main() {