Skip to content

Commit

Permalink
Auto merge of #1918 - RalfJung:simd_basics, r=RalfJung
Browse files Browse the repository at this point in the history
portable SIMD: basic binops

First steps towards #1912. Requires rust-lang/rust#90999.
  • Loading branch information
bors committed Nov 21, 2021
2 parents 8c700f5 + 84027dc commit 763a445
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
c9c4b5d7276297679387189d96a952f2b760e7ad
5bc98076f37dd8c1476de4bbe0515c55a65332b7
26 changes: 26 additions & 0 deletions src/shims/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,32 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write_scalar(res, dest)?;
}

// SIMD operations
"simd_add" | "simd_sub" | "simd_mul" | "simd_div" => {
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)?;
let (dest, dest_len) = this.place_to_simd(dest)?;

assert_eq!(dest_len, left_len);
assert_eq!(dest_len, right_len);

let op = match intrinsic_name {
"simd_add" => mir::BinOp::Add,
"simd_sub" => mir::BinOp::Sub,
"simd_mul" => mir::BinOp::Mul,
"simd_div" => mir::BinOp::Div,
_ => unreachable!(),
};

for i in 0..dest_len {
let left = this.read_immediate(&this.mplace_index(&left, i)?.into())?;
let right = this.read_immediate(&this.mplace_index(&right, i)?.into())?;
let dest = this.mplace_index(&dest, i)?.into();
this.binop_ignore_overflow(op, &left, &right, &dest)?;
}
}

// Atomic operations
"atomic_load" => this.atomic_load(args, dest, AtomicReadOp::SeqCst)?,
"atomic_load_relaxed" => this.atomic_load(args, dest, AtomicReadOp::Relaxed)?,
Expand Down
27 changes: 27 additions & 0 deletions tests/run-pass/portable-simd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#![feature(portable_simd)]
use std::simd::*;

fn simd_ops_f32() {
let a = f32x4::splat(10.0);
let 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, 14.0]));
assert_eq!(a - b, f32x4::from_array([9.0, 8.0, 7.0, 6.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]));
assert_eq!(a / 2.0, f32x4::splat(5.0));
}

fn simd_ops_i32() {
let a = i32x4::splat(10);
let b = i32x4::from_array([1, 2, 3, 4]);
assert_eq!(a + b, i32x4::from_array([11, 12, 13, 14]));
assert_eq!(a - b, i32x4::from_array([9, 8, 7, 6]));
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));
}

fn main() {
simd_ops_f32();
simd_ops_i32();
}

0 comments on commit 763a445

Please sign in to comment.