@@ -200,7 +200,7 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
200
200
}
201
201
} else {
202
202
// 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!)
204
204
match self . layout . fields {
205
205
FieldsShape :: Array { count, .. } => Ok ( count) ,
206
206
_ => bug ! ( "len not supported on sized type {:?}" , self . layout. ty) ,
@@ -533,6 +533,22 @@ where
533
533
} )
534
534
}
535
535
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
+
536
552
/// Gets the place of a field inside the place, and also the field's type.
537
553
/// Just a convenience function, but used quite a bit.
538
554
/// This is the only projection that might have a side-effect: We cannot project
@@ -594,6 +610,16 @@ where
594
610
} )
595
611
}
596
612
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
+
597
623
/// Computes a place. You should only use this if you intend to write into this
598
624
/// place; for reading, a more efficient alternative is `eval_place_for_read`.
599
625
pub fn eval_place (
0 commit comments