Skip to content

Commit

Permalink
implement simd_scatter
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Mar 10, 2022
1 parent 576e2bb commit 41ffce1
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 7 deletions.
26 changes: 22 additions & 4 deletions src/shims/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let no = this.read_immediate(&this.mplace_index(&no, i)?.into())?;
let dest = this.mplace_index(&dest, i)?;

let mask = simd_element_to_bool(mask)?;
let val = if mask { yes } else { no };
let val = if simd_element_to_bool(mask)? { yes } else { no };
this.write_immediate(*val, &dest.into())?;
}
}
Expand Down Expand Up @@ -670,8 +669,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let mask = this.read_immediate(&this.mplace_index(&mask, i)?.into())?;
let dest = this.mplace_index(&dest, i)?;

let mask = simd_element_to_bool(mask)?;
let val = if mask {
let val = if simd_element_to_bool(mask)? {
let place = this.deref_operand(&ptr.into())?;
this.read_immediate(&place.into())?
} else {
Expand All @@ -680,6 +678,26 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write_immediate(*val, &dest.into())?;
}
}
"simd_scatter" => {
let &[ref value, ref ptrs, ref mask] = check_arg_count(args)?;
let (value, value_len) = this.operand_to_simd(value)?;
let (ptrs, ptrs_len) = this.operand_to_simd(ptrs)?;
let (mask, mask_len) = this.operand_to_simd(mask)?;

assert_eq!(ptrs_len, value_len);
assert_eq!(ptrs_len, mask_len);

for i in 0..ptrs_len {
let value = this.read_immediate(&this.mplace_index(&value, i)?.into())?;
let ptr = this.read_immediate(&this.mplace_index(&ptrs, i)?.into())?;
let mask = this.read_immediate(&this.mplace_index(&mask, i)?.into())?;

if simd_element_to_bool(mask)? {
let place = this.deref_operand(&ptr.into())?;
this.write_immediate(*value, &place.into())?;
}
}
}

// Atomic operations
"atomic_load" => this.atomic_load(args, dest, AtomicReadOp::SeqCst)?,
Expand Down
4 changes: 2 additions & 2 deletions tests/compile-fail/intrinsics/simd-gather.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// error-pattern: out-of-bounds
// error-pattern: pointer to 1 byte starting at offset 9 is out-of-bounds
#![feature(portable_simd)]
use std::simd::*;

fn main() { unsafe {
let vec: &[i16] = &[10, 11, 12, 13, 14, 15, 16, 17, 18];
let vec: &[i8] = &[10, 11, 12, 13, 14, 15, 16, 17, 18];
let idxs = Simd::from_array([9, 3, 0, 17]);
let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0));
} }
9 changes: 9 additions & 0 deletions tests/compile-fail/intrinsics/simd-scatter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// error-pattern: pointer to 1 byte starting at offset 9 is out-of-bounds
#![feature(portable_simd)]
use std::simd::*;

fn main() { unsafe {
let mut vec: Vec<i8> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
let idxs = Simd::from_array([9, 3, 0, 17]);
Simd::from_array([-27, 82, -41, 124]).scatter_select_unchecked(&mut vec, Mask::splat(true), idxs);
} }
6 changes: 5 additions & 1 deletion tests/run-pass/portable-simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,14 @@ fn simd_swizzle() {
}

fn simd_gather_scatter() {
let vec: &[i16] = &[10, 11, 12, 13, 14, 15, 16, 17, 18];
let mut vec: Vec<i16> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
let idxs = Simd::from_array([9, 3, 0, 17]);
let result = Simd::gather_or_default(&vec, idxs); // Note the lane that is out-of-bounds.
assert_eq!(result, Simd::from_array([0, 13, 10, 0]));

let idxs = Simd::from_array([9, 3, 0, 0]);
Simd::from_array([-27, 82, -41, 124]).scatter(&mut vec, idxs);
assert_eq!(vec, vec![124, 11, 12, 82, 14, 15, 16, 17, 18]);
}

fn simd_intrinsics() {
Expand Down

0 comments on commit 41ffce1

Please sign in to comment.