Skip to content

Commit a80f69c

Browse files
authored
Rollup merge of rust-lang#66468 - RalfJung:simd-cleanup, r=oli-obk
Cleanup Miri SIMD intrinsics r? @oli-obk @eddyb Cc @gnzlbg
2 parents 7186de2 + 5e115a2 commit a80f69c

File tree

6 files changed

+41
-39
lines changed

6 files changed

+41
-39
lines changed

src/librustc/ty/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
697697
// SIMD vector types.
698698
ty::Adt(def, ..) if def.repr.simd() => {
699699
let element = self.layout_of(ty.simd_type(tcx))?;
700-
let count = ty.simd_size(tcx) as u64;
700+
let count = ty.simd_size(tcx);
701701
assert!(count > 0);
702702
let scalar = match element.abi {
703703
Abi::Scalar(ref scalar) => scalar.clone(),

src/librustc/ty/sty.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -1815,20 +1815,30 @@ impl<'tcx> TyS<'tcx> {
18151815

18161816
pub fn simd_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
18171817
match self.kind {
1818-
Adt(def, substs) => {
1819-
def.non_enum_variant().fields[0].ty(tcx, substs)
1820-
}
1818+
Adt(def, substs) => def.non_enum_variant().fields[0].ty(tcx, substs),
18211819
_ => bug!("simd_type called on invalid type")
18221820
}
18231821
}
18241822

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

1832+
pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
1833+
match self.kind {
1834+
Adt(def, substs) => {
1835+
let variant = def.non_enum_variant();
1836+
(variant.fields.len() as u64, variant.fields[0].ty(tcx, substs))
1837+
}
1838+
_ => bug!("simd_size_and_type called on invalid type")
1839+
}
1840+
}
1841+
18321842
#[inline]
18331843
pub fn is_region_ptr(&self) -> bool {
18341844
match self.kind {

src/librustc_codegen_llvm/intrinsic.rs

+14-13
Original file line numberDiff line numberDiff line change
@@ -1105,8 +1105,8 @@ fn generic_simd_intrinsic(
11051105
let m_len = match in_ty.kind {
11061106
// Note that this `.unwrap()` crashes for isize/usize, that's sort
11071107
// of intentional as there's not currently a use case for that.
1108-
ty::Int(i) => i.bit_width().unwrap(),
1109-
ty::Uint(i) => i.bit_width().unwrap(),
1108+
ty::Int(i) => i.bit_width().unwrap() as u64,
1109+
ty::Uint(i) => i.bit_width().unwrap() as u64,
11101110
_ => return_error!("`{}` is not an integral type", in_ty),
11111111
};
11121112
require_simd!(arg_tys[1], "argument");
@@ -1116,7 +1116,7 @@ fn generic_simd_intrinsic(
11161116
m_len, v_len
11171117
);
11181118
let i1 = bx.type_i1();
1119-
let i1xn = bx.type_vector(i1, m_len as u64);
1119+
let i1xn = bx.type_vector(i1, m_len);
11201120
let m_i1s = bx.bitcast(args[0].immediate(), i1xn);
11211121
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
11221122
}
@@ -1160,7 +1160,7 @@ fn generic_simd_intrinsic(
11601160
}
11611161

11621162
if name.starts_with("simd_shuffle") {
1163-
let n: usize = name["simd_shuffle".len()..].parse().unwrap_or_else(|_|
1163+
let n: u64 = name["simd_shuffle".len()..].parse().unwrap_or_else(|_|
11641164
span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?"));
11651165

11661166
require_simd!(ret_ty, "return");
@@ -1175,7 +1175,7 @@ fn generic_simd_intrinsic(
11751175
in_elem, in_ty,
11761176
ret_ty, ret_ty.simd_type(tcx));
11771177

1178-
let total_len = in_len as u128 * 2;
1178+
let total_len = u128::from(in_len) * 2;
11791179

11801180
let vector = args[2].immediate();
11811181

@@ -1251,7 +1251,7 @@ fn generic_simd_intrinsic(
12511251
// trailing bits.
12521252
let expected_int_bits = in_len.max(8);
12531253
match ret_ty.kind {
1254-
ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => (),
1254+
ty::Uint(i) if i.bit_width() == Some(expected_int_bits as usize) => (),
12551255
_ => return_error!(
12561256
"bitmask `{}`, expected `u{}`",
12571257
ret_ty, expected_int_bits
@@ -1276,7 +1276,8 @@ fn generic_simd_intrinsic(
12761276

12771277
// Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position.
12781278
let shift_indices = vec![
1279-
bx.cx.const_int(bx.type_ix(in_elem_bitwidth as _), (in_elem_bitwidth - 1) as _); in_len
1279+
bx.cx.const_int(bx.type_ix(in_elem_bitwidth as _), (in_elem_bitwidth - 1) as _);
1280+
in_len as _
12801281
];
12811282
let i_xn_msb = bx.lshr(i_xn, bx.const_vector(shift_indices.as_slice()));
12821283
// Truncate vector to an <i1 x N>
@@ -1291,7 +1292,7 @@ fn generic_simd_intrinsic(
12911292
name: &str,
12921293
in_elem: &::rustc::ty::TyS<'_>,
12931294
in_ty: &::rustc::ty::TyS<'_>,
1294-
in_len: usize,
1295+
in_len: u64,
12951296
bx: &mut Builder<'a, 'll, 'tcx>,
12961297
span: Span,
12971298
args: &[OperandRef<'tcx, &'ll Value>],
@@ -1400,7 +1401,7 @@ fn generic_simd_intrinsic(
14001401
// FIXME: use:
14011402
// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Function.h#L182
14021403
// https://github.com/llvm-mirror/llvm/blob/master/include/llvm/IR/Intrinsics.h#L81
1403-
fn llvm_vector_str(elem_ty: Ty<'_>, vec_len: usize, no_pointers: usize) -> String {
1404+
fn llvm_vector_str(elem_ty: Ty<'_>, vec_len: u64, no_pointers: usize) -> String {
14041405
let p0s: String = "p0".repeat(no_pointers);
14051406
match elem_ty.kind {
14061407
ty::Int(v) => format!("v{}{}i{}", vec_len, p0s, v.bit_width().unwrap()),
@@ -1410,7 +1411,7 @@ fn generic_simd_intrinsic(
14101411
}
14111412
}
14121413

1413-
fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: Ty<'_>, vec_len: usize,
1414+
fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: Ty<'_>, vec_len: u64,
14141415
mut no_pointers: usize) -> &'ll Type {
14151416
// FIXME: use cx.layout_of(ty).llvm_type() ?
14161417
let mut elem_ty = match elem_ty.kind {
@@ -1423,7 +1424,7 @@ fn generic_simd_intrinsic(
14231424
elem_ty = cx.type_ptr_to(elem_ty);
14241425
no_pointers -= 1;
14251426
}
1426-
cx.type_vector(elem_ty, vec_len as u64)
1427+
cx.type_vector(elem_ty, vec_len)
14271428
}
14281429

14291430

@@ -1506,7 +1507,7 @@ fn generic_simd_intrinsic(
15061507
// Truncate the mask vector to a vector of i1s:
15071508
let (mask, mask_ty) = {
15081509
let i1 = bx.type_i1();
1509-
let i1xn = bx.type_vector(i1, in_len as u64);
1510+
let i1xn = bx.type_vector(i1, in_len);
15101511
(bx.trunc(args[2].immediate(), i1xn), i1xn)
15111512
};
15121513

@@ -1606,7 +1607,7 @@ fn generic_simd_intrinsic(
16061607
// Truncate the mask vector to a vector of i1s:
16071608
let (mask, mask_ty) = {
16081609
let i1 = bx.type_i1();
1609-
let i1xn = bx.type_vector(i1, in_len as u64);
1610+
let i1xn = bx.type_vector(i1, in_len);
16101611
(bx.trunc(args[2].immediate(), i1xn), i1xn)
16111612
};
16121613

src/librustc_mir/interpret/intrinsics.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
302302
self.copy_op_transmute(args[0], dest)?;
303303
}
304304
"simd_insert" => {
305-
let index = self.read_scalar(args[1])?.to_u32()? as u64;
306-
let scalar = args[2];
305+
let index = u64::from(self.read_scalar(args[1])?.to_u32()?);
306+
let elem = args[2];
307307
let input = args[0];
308-
let (len, e_ty) = self.read_vector_ty(input);
308+
let (len, e_ty) = input.layout.ty.simd_size_and_type(self.tcx.tcx);
309309
assert!(
310310
index < len,
311311
"Index `{}` must be in bounds of vector type `{}`: `[0, {})`",
@@ -317,24 +317,24 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
317317
dest.layout.ty, input.layout.ty
318318
);
319319
assert_eq!(
320-
scalar.layout.ty, e_ty,
321-
"Scalar type `{}` must match vector element type `{}`",
322-
scalar.layout.ty, e_ty
320+
elem.layout.ty, e_ty,
321+
"Scalar element type `{}` must match vector element type `{}`",
322+
elem.layout.ty, e_ty
323323
);
324324

325325
for i in 0..len {
326326
let place = self.place_field(dest, i)?;
327327
let value = if i == index {
328-
scalar
328+
elem
329329
} else {
330330
self.operand_field(input, i)?
331331
};
332332
self.copy_op(value, place)?;
333333
}
334334
}
335335
"simd_extract" => {
336-
let index = self.read_scalar(args[1])?.to_u32()? as _;
337-
let (len, e_ty) = self.read_vector_ty(args[0]);
336+
let index = u64::from(self.read_scalar(args[1])?.to_u32()?);
337+
let (len, e_ty) = args[0].layout.ty.simd_size_and_type(self.tcx.tcx);
338338
assert!(
339339
index < len,
340340
"index `{}` is out-of-bounds of vector type `{}` with length `{}`",

src/librustc_mir/interpret/operand.rs

-11
Original file line numberDiff line numberDiff line change
@@ -315,17 +315,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
315315
}
316316
}
317317

318-
/// Read vector length and element type
319-
pub fn read_vector_ty(
320-
&self, op: OpTy<'tcx, M::PointerTag>
321-
) -> (u64, &rustc::ty::TyS<'tcx>) {
322-
if let layout::Abi::Vector { .. } = op.layout.abi {
323-
(op.layout.ty.simd_size(*self.tcx) as _, op.layout.ty.simd_type(*self.tcx))
324-
} else {
325-
bug!("Type `{}` is not a SIMD vector type", op.layout.ty)
326-
}
327-
}
328-
329318
/// Read a scalar from a place
330319
pub fn read_scalar(
331320
&self,

src/librustc_mir/interpret/terminator.rs

+2
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
264264

265265
match instance.def {
266266
ty::InstanceDef::Intrinsic(..) => {
267+
assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
268+
267269
let old_stack = self.cur_frame();
268270
let old_bb = self.frame().block;
269271
M::call_intrinsic(self, span, instance, args, dest, ret, unwind)?;

0 commit comments

Comments
 (0)