Skip to content

Commit

Permalink
Auto merge of rust-lang#3655 - RalfJung:simd-bitmask, r=RalfJung
Browse files Browse the repository at this point in the history
portable-simd: add test for non-power-of-2 bitmask

`@calebzulawski` is that the intended behavior? Specifically for arrays, the bitmask `[1, 0, 0, 1, 0, 0, 1, 0, 1, 0]` becomes
- `[0b01001001, 0b01]` on little endian
- `[0b10010010, 0b10]` on big endian
  • Loading branch information
bors committed Jun 8, 2024
2 parents 4d5fd11 + ca3d93a commit 1f1dd65
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion src/tools/miri/tests/pass/intrinsics/portable-simd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@compile-flags: -Zmiri-strict-provenance
#![feature(portable_simd, adt_const_params, core_intrinsics)]
#![feature(portable_simd, adt_const_params, core_intrinsics, repr_simd)]
#![allow(incomplete_features, internal_features)]
use std::intrinsics::simd as intrinsics;
use std::ptr;
Expand Down Expand Up @@ -318,6 +318,44 @@ fn simd_mask() {
assert_eq!(selected1, i32x4::from_array([0, 0, 0, 1]));
assert_eq!(selected2, selected1);
}

// Non-power-of-2 multi-byte mask.
#[repr(simd, packed)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, Debug, PartialEq)]
struct i32x10(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32);
impl i32x10 {
fn splat(x: i32) -> Self {
Self(x, x, x, x, x, x, x, x, x, x)
}
fn from_array(a: [i32; 10]) -> Self {
unsafe { std::mem::transmute(a) }
}
}
unsafe {
let mask = i32x10::from_array([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0]);
let bitmask1: u16 = simd_bitmask(mask);
let bitmask2: [u8; 2] = simd_bitmask(mask);
if cfg!(target_endian = "little") {
assert_eq!(bitmask1, 0b0101001011);
assert_eq!(bitmask2, [0b01001011, 0b01]);
} else {
assert_eq!(bitmask1, 0b1101001010);
assert_eq!(bitmask2, [0b11, 0b01001010]);
}
let selected1 = simd_select_bitmask::<u16, _>(
if cfg!(target_endian = "little") { 0b0101001011 } else { 0b1101001010 },
i32x10::splat(!0), // yes
i32x10::splat(0), // no
);
let selected2 = simd_select_bitmask::<[u8; 2], _>(
if cfg!(target_endian = "little") { [0b01001011, 0b01] } else { [0b11, 0b01001010] },
i32x10::splat(!0), // yes
i32x10::splat(0), // no
);
assert_eq!(selected1, mask);
assert_eq!(selected2, selected1);
}
}

fn simd_cast() {
Expand Down

0 comments on commit 1f1dd65

Please sign in to comment.