Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #66607

Merged
merged 20 commits into from
Nov 21, 2019
Merged
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
@@ -1814,20 +1814,30 @@ impl<'tcx> TyS<'tcx> {

pub fn simd_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match self.kind {
Adt(def, substs) => {
def.non_enum_variant().fields[0].ty(tcx, substs)
}
Adt(def, substs) => def.non_enum_variant().fields[0].ty(tcx, substs),
_ => bug!("simd_type called on invalid type")
}
}

pub fn simd_size(&self, _cx: TyCtxt<'_>) -> usize {
pub fn simd_size(&self, _tcx: TyCtxt<'tcx>) -> usize {
// Parameter currently unused, but probably needed in the future to
// allow `#[repr(simd)] struct Simd<T, const N: usize>([T; N]);`.
match self.kind {
Adt(def, _) => def.non_enum_variant().fields.len(),
_ => bug!("simd_size called on invalid type")
}
}

pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (usize, Ty<'tcx>) {
match self.kind {
Adt(def, substs) => {
let variant = def.non_enum_variant();
(variant.fields.len(), variant.fields[0].ty(tcx, substs))
}
_ => bug!("simd_size_and_type called on invalid type")
}
}

#[inline]
pub fn is_region_ptr(&self) -> bool {
match self.kind {
21 changes: 11 additions & 10 deletions src/librustc_mir/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -302,10 +302,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.copy_op_transmute(args[0], dest)?;
}
"simd_insert" => {
let index = self.read_scalar(args[1])?.to_u32()? as u64;
let scalar = args[2];
let index = u64::from(self.read_scalar(args[1])?.to_u32()?);
let elem = args[2];
let input = args[0];
let (len, e_ty) = self.read_vector_ty(input);
let (len, e_ty) = input.layout.ty.simd_size_and_type(self.tcx.tcx);
let len = len as u64;
assert!(
index < len,
"Index `{}` must be in bounds of vector type `{}`: `[0, {})`",
@@ -317,26 +318,26 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
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
elem.layout.ty, e_ty,
"Scalar element type `{}` must match vector element type `{}`",
elem.layout.ty, e_ty
);

for i in 0..len {
let place = self.place_field(dest, i)?;
let value = if i == index {
scalar
elem
} else {
self.operand_field(input, i)?
};
self.copy_op(value, place)?;
}
}
"simd_extract" => {
let index = self.read_scalar(args[1])?.to_u32()? as _;
let (len, e_ty) = self.read_vector_ty(args[0]);
let index = u64::from(self.read_scalar(args[1])?.to_u32()?);
let (len, e_ty) = args[0].layout.ty.simd_size_and_type(self.tcx.tcx);
assert!(
index < len,
index < len as u64,
"index `{}` is out-of-bounds of vector type `{}` with length `{}`",
index, e_ty, len
);
11 changes: 0 additions & 11 deletions src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
@@ -315,17 +315,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}

/// 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 SIMD vector type", op.layout.ty)
}
}

/// Read a scalar from a place
pub fn read_scalar(
&self,