@@ -200,7 +200,7 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
200200 }
201201 } else {
202202 // Go through the layout. There are lots of types that support a length,
203- // e.g., SIMD types.
203+ // e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
204204 match self . layout . fields {
205205 FieldsShape :: Array { count, .. } => Ok ( count) ,
206206 _ => bug ! ( "len not supported on sized type {:?}" , self . layout. ty) ,
@@ -533,6 +533,22 @@ where
533533 } )
534534 }
535535
536+ /// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
537+ /// Also returns the number of elements.
538+ pub fn mplace_to_simd (
539+ & self ,
540+ base : & MPlaceTy < ' tcx , M :: PointerTag > ,
541+ ) -> InterpResult < ' tcx , ( MPlaceTy < ' tcx , M :: PointerTag > , u64 ) > {
542+ // Basically we just transmute this place into an array following simd_size_and_type.
543+ // (Transmuting is okay since this is an in-memory place. We also double-check the size
544+ // stays the same.)
545+ let ( len, e_ty) = base. layout . ty . simd_size_and_type ( * self . tcx ) ;
546+ let array = self . tcx . mk_array ( e_ty, len) ;
547+ let layout = self . layout_of ( array) ?;
548+ assert_eq ! ( layout. size, base. layout. size) ;
549+ Ok ( ( MPlaceTy { layout, ..* base } , len) )
550+ }
551+
536552 /// Gets the place of a field inside the place, and also the field's type.
537553 /// Just a convenience function, but used quite a bit.
538554 /// This is the only projection that might have a side-effect: We cannot project
@@ -594,6 +610,16 @@ where
594610 } )
595611 }
596612
613+ /// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
614+ /// Also returns the number of elements.
615+ pub fn place_to_simd (
616+ & mut self ,
617+ base : & PlaceTy < ' tcx , M :: PointerTag > ,
618+ ) -> InterpResult < ' tcx , ( MPlaceTy < ' tcx , M :: PointerTag > , u64 ) > {
619+ let mplace = self . force_allocation ( base) ?;
620+ self . mplace_to_simd ( & mplace)
621+ }
622+
597623 /// Computes a place. You should only use this if you intend to write into this
598624 /// place; for reading, a more efficient alternative is `eval_place_for_read`.
599625 pub fn eval_place (
0 commit comments