Skip to content

Commit c4b4c28

Browse files
committed
Auto merge of #3462 - eduardosm:chunk-128, r=RalfJung
Make `split_simd_to_128bit_chunks` take only one operand It will allow more flexible uses in the future. This makes `split_simd_to_128bit_chunks` simpler, moving some of the complexity to its callers.
2 parents d4da2cc + 2d90a21 commit c4b4c28

File tree

1 file changed

+33
-44
lines changed

1 file changed

+33
-44
lines changed

src/shims/x86/mod.rs

Lines changed: 33 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)