Skip to content

Commit a534bbb

Browse files
committed
portable SIMD: add rem intrinsic; test div and rem intrinsic UB
1 parent 4f0faed commit a534bbb

File tree

6 files changed

+34
-1
lines changed

6 files changed

+34
-1
lines changed

src/shims/intrinsics.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
306306
}
307307

308308
// SIMD operations
309-
"simd_add" | "simd_sub" | "simd_mul" | "simd_div" => {
309+
"simd_add" | "simd_sub" | "simd_mul" | "simd_div" | "simd_rem" => {
310310
let &[ref left, ref right] = check_arg_count(args)?;
311311
let (left, left_len) = this.operand_to_simd(left)?;
312312
let (right, right_len) = this.operand_to_simd(right)?;
@@ -320,6 +320,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
320320
"simd_sub" => mir::BinOp::Sub,
321321
"simd_mul" => mir::BinOp::Mul,
322322
"simd_div" => mir::BinOp::Div,
323+
"simd_rem" => mir::BinOp::Rem,
323324
_ => unreachable!(),
324325
};
325326

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(platform_intrinsics, repr_simd)]
2+
3+
extern "platform-intrinsic" {
4+
pub(crate) fn simd_div<T>(x: T, y: T) -> T;
5+
}
6+
7+
#[repr(simd)]
8+
#[allow(non_camel_case_types)]
9+
struct i32x2(i32, i32);
10+
11+
fn main() { unsafe {
12+
let x = i32x2(1, 1);
13+
let y = i32x2(1, 0);
14+
simd_div(x, y); //~ERROR Undefined Behavior: dividing by zero
15+
} }
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(platform_intrinsics, repr_simd)]
2+
3+
extern "platform-intrinsic" {
4+
pub(crate) fn simd_rem<T>(x: T, y: T) -> T;
5+
}
6+
7+
#[repr(simd)]
8+
#[allow(non_camel_case_types)]
9+
struct i32x2(i32, i32);
10+
11+
fn main() { unsafe {
12+
let x = i32x2(1, 1);
13+
let y = i32x2(1, 0);
14+
simd_rem(x, y); //~ERROR Undefined Behavior: calculating the remainder with a divisor of zero
15+
} }

tests/run-pass/portable-simd.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ fn simd_ops_f32() {
99
assert_eq!(a * b, f32x4::from_array([10.0, 20.0, 30.0, 40.0]));
1010
assert_eq!(b / a, f32x4::from_array([0.1, 0.2, 0.3, 0.4]));
1111
assert_eq!(a / 2.0, f32x4::splat(5.0));
12+
assert_eq!(a % b, f32x4::from_array([0.0, 0.0, 1.0, 2.0]));
1213
}
1314

1415
fn simd_ops_i32() {
@@ -19,6 +20,7 @@ fn simd_ops_i32() {
1920
assert_eq!(a * b, i32x4::from_array([10, 20, 30, 40]));
2021
assert_eq!(a / b, i32x4::from_array([10, 5, 3, 2]));
2122
assert_eq!(a / 2, i32x4::splat(5));
23+
assert_eq!(a % b, i32x4::from_array([0, 0, 1, 2]));
2224
}
2325

2426
fn main() {

0 commit comments

Comments
 (0)