Skip to content

Commit

Permalink
fix simd_bitmask shorter than a byte on big-endian
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Mar 17, 2022
1 parent b5d3a25 commit 1b1321a
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 8 deletions.
13 changes: 6 additions & 7 deletions src/shims/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand All @@ -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"
Expand Down Expand Up @@ -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)?;
Expand Down Expand Up @@ -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
}
}
2 changes: 1 addition & 1 deletion tests/run-pass/portable-simd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ fn simd_mask() {
let values = [false, false, false, true];
let mask = Mask::<i64, 4>::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::<i64, 4>::from_bitmask(bitmask), mask);
}

Expand Down

0 comments on commit 1b1321a

Please sign in to comment.