@@ -664,54 +664,35 @@ fn convert_float_to_int<'tcx>(
664664 Ok ( ( ) )
665665}
666666
667- /// Splits `left`, `right` and `dest` (which must be SIMD vectors)
668- /// into 128-bit chuncks.
669- ///
670- /// `left`, `right` and `dest` cannot have different types.
667+ /// Splits `op` (which must be a SIMD vector) into 128-bit chuncks.
671668///
672669/// Returns a tuple where:
673670/// * The first element is the number of 128-bit chunks (let's call it `N`).
674671/// * The second element is the number of elements per chunk (let's call it `M`).
675- /// * The third element is the `left` vector split into chunks, i.e, it's
676- /// type is `[[T; M]; N]`.
677- /// * The fourth element is the `right` vector split into chunks.
678- /// * The fifth element is the `dest` vector split into chunks.
679- fn split_simd_to_128bit_chunks < ' tcx > (
672+ /// * The third element is the `op` vector split into chunks, i.e, it's
673+ /// type is `[[T; M]; N]` where `T` is the element type of `op`.
674+ fn split_simd_to_128bit_chunks < ' tcx , P : Projectable < ' tcx , Provenance > > (
680675 this : & mut crate :: MiriInterpCx < ' _ , ' tcx > ,
681- left : & OpTy < ' tcx , Provenance > ,
682- right : & OpTy < ' tcx , Provenance > ,
683- dest : & MPlaceTy < ' tcx , Provenance > ,
684- ) -> InterpResult <
685- ' tcx ,
686- ( u64 , u64 , MPlaceTy < ' tcx , Provenance > , MPlaceTy < ' tcx , Provenance > , MPlaceTy < ' tcx , Provenance > ) ,
687- > {
688- assert_eq ! ( dest. layout, left. layout) ;
689- assert_eq ! ( dest. layout, right. layout) ;
676+ op : & P ,
677+ ) -> InterpResult < ' tcx , ( u64 , u64 , P ) > {
678+ let simd_layout = op. layout ( ) ;
679+ let ( simd_len, element_ty) = simd_layout. ty . simd_size_and_type ( this. tcx . tcx ) ;
690680
691- let ( left, left_len) = this. operand_to_simd ( left) ?;
692- let ( right, right_len) = this. operand_to_simd ( right) ?;
693- let ( dest, dest_len) = this. mplace_to_simd ( dest) ?;
694-
695- assert_eq ! ( dest_len, left_len) ;
696- assert_eq ! ( dest_len, right_len) ;
697-
698- assert_eq ! ( dest. layout. size. bits( ) % 128 , 0 ) ;
699- let num_chunks = dest. layout . size . bits ( ) / 128 ;
700- assert_eq ! ( dest_len. checked_rem( num_chunks) , Some ( 0 ) ) ;
701- let items_per_chunk = dest_len. checked_div ( num_chunks) . unwrap ( ) ;
681+ assert_eq ! ( simd_layout. size. bits( ) % 128 , 0 ) ;
682+ let num_chunks = simd_layout. size . bits ( ) / 128 ;
683+ let items_per_chunk = simd_len. checked_div ( num_chunks) . unwrap ( ) ;
702684
703685 // Transmute to `[[T; items_per_chunk]; num_chunks]`
704- let element_layout = left. layout . field ( this, 0 ) ;
705- let chunked_layout = this. layout_of ( Ty :: new_array (
706- this. tcx . tcx ,
707- Ty :: new_array ( this. tcx . tcx , element_layout. ty , items_per_chunk) ,
708- num_chunks,
709- ) ) ?;
710- let left = left. transmute ( chunked_layout, this) ?;
711- let right = right. transmute ( chunked_layout, this) ?;
712- let dest = dest. transmute ( chunked_layout, this) ?;
713-
714- Ok ( ( num_chunks, items_per_chunk, left, right, dest) )
686+ let chunked_layout = this
687+ . layout_of ( Ty :: new_array (
688+ this. tcx . tcx ,
689+ Ty :: new_array ( this. tcx . tcx , element_ty, items_per_chunk) ,
690+ num_chunks,
691+ ) )
692+ . unwrap ( ) ;
693+ let chunked_op = op. transmute ( chunked_layout, this) ?;
694+
695+ Ok ( ( num_chunks, items_per_chunk, chunked_op) )
715696}
716697
717698/// Horizontaly performs `which` operation on adjacent values of
@@ -731,8 +712,12 @@ fn horizontal_bin_op<'tcx>(
731712 right : & OpTy < ' tcx , Provenance > ,
732713 dest : & MPlaceTy < ' tcx , Provenance > ,
733714) -> InterpResult < ' tcx , ( ) > {
734- let ( num_chunks, items_per_chunk, left, right, dest) =
735- split_simd_to_128bit_chunks ( this, left, right, dest) ?;
715+ assert_eq ! ( left. layout, dest. layout) ;
716+ assert_eq ! ( right. layout, dest. layout) ;
717+
718+ let ( num_chunks, items_per_chunk, left) = split_simd_to_128bit_chunks ( this, left) ?;
719+ let ( _, _, right) = split_simd_to_128bit_chunks ( this, right) ?;
720+ let ( _, _, dest) = split_simd_to_128bit_chunks ( this, dest) ?;
736721
737722 let middle = items_per_chunk / 2 ;
738723 for i in 0 ..num_chunks {
@@ -779,8 +764,12 @@ fn conditional_dot_product<'tcx>(
779764 imm : & OpTy < ' tcx , Provenance > ,
780765 dest : & MPlaceTy < ' tcx , Provenance > ,
781766) -> InterpResult < ' tcx , ( ) > {
782- let ( num_chunks, items_per_chunk, left, right, dest) =
783- split_simd_to_128bit_chunks ( this, left, right, dest) ?;
767+ assert_eq ! ( left. layout, dest. layout) ;
768+ assert_eq ! ( right. layout, dest. layout) ;
769+
770+ let ( num_chunks, items_per_chunk, left) = split_simd_to_128bit_chunks ( this, left) ?;
771+ let ( _, _, right) = split_simd_to_128bit_chunks ( this, right) ?;
772+ let ( _, _, dest) = split_simd_to_128bit_chunks ( this, dest) ?;
784773
785774 let element_layout = left. layout . field ( this, 0 ) . field ( this, 0 ) ;
786775 assert ! ( items_per_chunk <= 4 ) ;
0 commit comments