Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
gnzlbg committed Sep 25, 2019
1 parent 02b3234 commit 5976674
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 58 deletions.
57 changes: 44 additions & 13 deletions src/librustc_mir/interpret/intrinsics.rs
Expand Up @@ -240,24 +240,55 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.copy_op_transmute(args[0], dest)?;
}
"simd_insert" => {
let mut vector = self.read_vector(args[0])?;
let index = self.read_scalar(args[1])?.to_u32()? as usize;
let index = self.read_scalar(args[1])?.to_u32()? as u64;
let scalar = self.read_immediate(args[2])?;
if vector[index].layout.size == scalar.layout.size {
vector[index] = scalar;
} else {
throw_ub_format!(
"Inserting `{}` with size `{}` to a vector element place of size `{}`",
scalar.layout.ty,
scalar.layout.size.bytes(), vector[index].layout.size.bytes()
);
let input = args[0];
let (len, e_ty) = self.read_vector_ty(input);
assert!(
index < len,
"index `{}` must be in bounds of vector type `{}`: `[0, {})`",
index, e_ty, len
);
assert_eq!(
args[0].layout, dest.layout,
"Return type `{}` must match vector type `{}`",
dest.layout.ty, input.layout.ty
);
assert_eq!(
scalar.layout.ty, e_ty,
"Scalar type `{}` must match vector element type `{}`",
scalar.layout.ty, e_ty
);

for i in 0..len {
let place = self.place_field(dest, index)?;
if i == index {
self.write_immediate(*scalar, place)?;
} else {
self.write_immediate(
*self.read_immediate(self.operand_field(input, index)?)?,
place
)?;
};
}
self.write_vector(vector, dest)?;
}
"simd_extract" => {
let index = self.read_scalar(args[1])?.to_u32()? as _;
let scalar = self.read_immediate(self.operand_field(args[0], index)?)?;
self.write_immediate(*scalar, dest)?;
let (len, e_ty) = self.read_vector_ty(args[0]);
assert!(
index < len,
"index `{}` must be in bounds of vector type `{}`: `[0, {})`",
index, e_ty, len
);
assert_eq!(
e_ty, dest.layout.ty,
"Return type `{}` must match vector element type `{}`",
dest.layout.ty, e_ty
);
self.write_immediate(
*self.read_immediate(self.operand_field(args[0], index)?)?,
dest
)?;
}
_ => return Ok(false),
}
Expand Down
19 changes: 8 additions & 11 deletions src/librustc_mir/interpret/operand.rs
Expand Up @@ -335,18 +335,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}

/// Read vector from operand `op`
pub fn read_vector(&self, op: OpTy<'tcx, M::PointerTag>)
-> InterpResult<'tcx, Vec<ImmTy<'tcx, M::PointerTag>>> {
if let layout::Abi::Vector { count, .. } = op.layout.abi {
assert_ne!(count, 0);
let mut scalars = Vec::new();
for index in 0..count {
scalars.push(self.read_immediate(self.operand_field(op, index as _)?)?);
}
Ok(scalars)
/// Read vector length and element type
pub fn read_vector_ty(
&self, op: OpTy<'tcx, M::PointerTag>
)
-> (u64, &rustc::ty::TyS<'tcx>) {
if let layout::Abi::Vector { .. } = op.layout.abi {
(op.layout.ty.simd_size(*self.tcx) as _, op.layout.ty.simd_type(*self.tcx))
} else {
bug!("type is not a vector: {:?}, abi: {:?}", op.layout.ty, op.layout.abi);
bug!("Type `{}` is not a SIMD vector type", op.layout.ty)
}
}

Expand Down
34 changes: 0 additions & 34 deletions src/librustc_mir/interpret/place.rs
Expand Up @@ -696,40 +696,6 @@ where
Ok(())
}

/// Writes the `scalar` to the `index`-th element of the `vector`.
pub fn write_scalar_to_vector(
&mut self,
scalar: ImmTy<'tcx, M::PointerTag>,
vector: PlaceTy<'tcx, M::PointerTag>,
index: usize,
) -> InterpResult<'tcx> {
let index = index as u64;
let place = self.place_field(vector, index)?;
self.write_immediate(*scalar, place)?;
Ok(())
}

/// Writes the `scalars` to the `vector`.
pub fn write_vector(
&mut self,
scalars: Vec<ImmTy<'tcx, M::PointerTag>>,
vector: PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
assert_ne!(scalars.len(), 0);
match vector.layout.ty.sty {
ty::Adt(def, ..) if def.repr.simd() => {
let tcx = &*self.tcx;
let count = vector.layout.ty.simd_size(*tcx);
assert_eq!(count, scalars.len());
for index in 0..scalars.len() {
self.write_scalar_to_vector(scalars[index], vector, index)?;
}
}
_ => bug!("not a vector"),
}
Ok(())
}

/// Write an `Immediate` to memory.
#[inline(always)]
pub fn write_immediate_to_mplace(
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/consts/const-eval/simd/insert_extract-fail.rs
Expand Up @@ -7,14 +7,21 @@

extern "platform-intrinsic" {
fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
fn simd_extract<T, U>(x: T, idx: u32) -> U;
}

const fn foo(x: i8x1) -> i8 {
// 42 is a i16 that does not fit in a i8
unsafe { simd_insert(x, 0_u32, 42_i16) }.0 //~ ERROR
}

const fn bar(x: i8x1) -> i16 {
// the i8 is not a i16:
unsafe { simd_extract(x, 0_u32) } //~ ERROR
}

fn main() {
const V: i8x1 = i8x1(13);
const X: i8 = foo(V);
const Y: i16 = bar(V);
}
17 changes: 17 additions & 0 deletions src/test/ui/consts/const-eval/simd/read_fail.rs
@@ -0,0 +1,17 @@
#![feature(const_fn)]
#![feature(platform_intrinsics)]
#![allow(non_camel_case_types)]

extern "platform-intrinsic" {
fn simd_extract<T, U>(x: T, idx: u32) -> U;
}

const fn foo(x: i8) -> i8 {
// i8 is not a vector type:
unsafe { simd_extract(x, 0_u32) } //~ ERROR
}

fn main() {
const V: i8 = 13;
const X: i8 = foo(V);
}

0 comments on commit 5976674

Please sign in to comment.