Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1f1dd65

Browse files
committed
Auto merge of rust-lang#3655 - RalfJung:simd-bitmask, r=RalfJung
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
2 parents 4d5fd11 + ca3d93a commit 1f1dd65

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

src/tools/miri/tests/pass/intrinsics/portable-simd.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@compile-flags: -Zmiri-strict-provenance
2-
#![feature(portable_simd, adt_const_params, core_intrinsics)]
2+
#![feature(portable_simd, adt_const_params, core_intrinsics, repr_simd)]
33
#![allow(incomplete_features, internal_features)]
44
use std::intrinsics::simd as intrinsics;
55
use std::ptr;
@@ -318,6 +318,44 @@ fn simd_mask() {
318318
assert_eq!(selected1, i32x4::from_array([0, 0, 0, 1]));
319319
assert_eq!(selected2, selected1);
320320
}
321+
322+
// Non-power-of-2 multi-byte mask.
323+
#[repr(simd, packed)]
324+
#[allow(non_camel_case_types)]
325+
#[derive(Copy, Clone, Debug, PartialEq)]
326+
struct i32x10(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32);
327+
impl i32x10 {
328+
fn splat(x: i32) -> Self {
329+
Self(x, x, x, x, x, x, x, x, x, x)
330+
}
331+
fn from_array(a: [i32; 10]) -> Self {
332+
unsafe { std::mem::transmute(a) }
333+
}
334+
}
335+
unsafe {
336+
let mask = i32x10::from_array([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0]);
337+
let bitmask1: u16 = simd_bitmask(mask);
338+
let bitmask2: [u8; 2] = simd_bitmask(mask);
339+
if cfg!(target_endian = "little") {
340+
assert_eq!(bitmask1, 0b0101001011);
341+
assert_eq!(bitmask2, [0b01001011, 0b01]);
342+
} else {
343+
assert_eq!(bitmask1, 0b1101001010);
344+
assert_eq!(bitmask2, [0b11, 0b01001010]);
345+
}
346+
let selected1 = simd_select_bitmask::<u16, _>(
347+
if cfg!(target_endian = "little") { 0b0101001011 } else { 0b1101001010 },
348+
i32x10::splat(!0), // yes
349+
i32x10::splat(0), // no
350+
);
351+
let selected2 = simd_select_bitmask::<[u8; 2], _>(
352+
if cfg!(target_endian = "little") { [0b01001011, 0b01] } else { [0b11, 0b01001010] },
353+
i32x10::splat(!0), // yes
354+
i32x10::splat(0), // no
355+
);
356+
assert_eq!(selected1, mask);
357+
assert_eq!(selected2, selected1);
358+
}
321359
}
322360

323361
fn simd_cast() {

0 commit comments

Comments
 (0)