From 1b1321a685f4d5e362786c1876dbcc9e2de866ba Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 17 Mar 2022 13:14:16 -0400 Subject: [PATCH] fix simd_bitmask shorter than a byte on big-endian --- src/shims/intrinsics.rs | 13 ++++++------- tests/run-pass/portable-simd.rs | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index 495ad93951..c344d0ff9c 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -685,7 +685,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx .unwrap(); for i in 0..dest_len { let mask = - mask & (1 << simd_bitmask_index(i, bitmask_len, this.data_layout().endian)); + mask & (1 << simd_bitmask_index(i, dest_len, this.data_layout().endian)); let yes = this.read_immediate(&this.mplace_index(&yes, i)?.into())?; let no = this.read_immediate(&this.mplace_index(&no, i)?.into())?; let dest = this.mplace_index(&dest, i)?; @@ -695,8 +695,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } for i in dest_len..bitmask_len { // If the mask is "padded", ensure that padding is all-zero. - let mask = - mask & (1 << simd_bitmask_index(i, bitmask_len, this.data_layout().endian)); + let mask = mask & (1 << i); if mask != 0 { throw_ub_format!( "a SIMD bitmask less than 8 bits long must be filled with 0s for the remaining bits" @@ -841,7 +840,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx for i in 0..op_len { let op = this.read_immediate(&this.mplace_index(&op, i)?.into())?; if simd_element_to_bool(op)? { - res |= 1 << simd_bitmask_index(i, bitmask_len, this.data_layout().endian); + res |= 1 << simd_bitmask_index(i, op_len, this.data_layout().endian); } } this.write_int(res, dest)?; @@ -1382,10 +1381,10 @@ fn simd_element_to_bool<'tcx>(elem: ImmTy<'tcx, Tag>) -> InterpResult<'tcx, bool }) } -fn simd_bitmask_index(idx: u64, bitmask_len: u64, endianess: Endian) -> u64 { - assert!(idx < bitmask_len); +fn simd_bitmask_index(idx: u64, vec_len: u64, endianess: Endian) -> u64 { + assert!(idx < vec_len); match endianess { Endian::Little => idx, - Endian::Big => bitmask_len - 1 - idx, // reverse order of bits + Endian::Big => vec_len - 1 - idx, // reverse order of bits } } diff --git a/tests/run-pass/portable-simd.rs b/tests/run-pass/portable-simd.rs index a74559b72b..99a64ea370 100644 --- a/tests/run-pass/portable-simd.rs +++ b/tests/run-pass/portable-simd.rs @@ -200,7 +200,7 @@ fn simd_mask() { let values = [false, false, false, true]; let mask = Mask::::from_array(values); let bitmask = mask.to_bitmask(); - assert_eq!(bitmask, 0b1000); + // FIXME fails until https://github.com/rust-lang/portable-simd/pull/267 lands: assert_eq!(bitmask, 0b1000); assert_eq!(Mask::::from_bitmask(bitmask), mask); }