about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-06-08 17:26:18 +0200
committerRalf Jung <post@ralfj.de>2024-06-08 19:19:01 +0200
commitca3d93aab050c87a18ee2142cc90e7ef79f405ea (patch)
tree211feb36c043aa901c1260a13d3e6a6f3115542e /src
parent20b3527771a6caf7910abdab530d2186ca1175cb (diff)
downloadrust-ca3d93aab050c87a18ee2142cc90e7ef79f405ea.tar.gz
rust-ca3d93aab050c87a18ee2142cc90e7ef79f405ea.zip
portable-simd: add test for non-power-of-2 bitmask
Diffstat (limited to 'src')
-rw-r--r--src/tools/miri/tests/pass/intrinsics/portable-simd.rs40
1 files changed, 39 insertions, 1 deletions
diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
index 248a57d6850..de87f153b6f 100644
--- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
+++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
@@ -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;
@@ -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() {