Skip to content

Commit 289c1d1

Browse files
committed
Fix bitmask vector bit order
1 parent e0e9a45 commit 289c1d1

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

crates/core_simd/src/masks/full_masks.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ where
157157
for x in bytes.as_mut() {
158158
*x = x.reverse_bits()
159159
}
160+
if N % 8 > 0 {
161+
bytes.as_mut()[N / 8] >>= 8 - N % 8;
162+
}
160163
}
161164

162165
bitmask.as_mut_array()[..bytes.as_ref().len()].copy_from_slice(bytes.as_ref());
@@ -180,6 +183,9 @@ where
180183
for x in bytes.as_mut() {
181184
*x = x.reverse_bits();
182185
}
186+
if N % 8 > 0 {
187+
bytes.as_mut()[N / 8] >>= 8 - N % 8;
188+
}
183189
}
184190

185191
// Compute the regular mask

crates/core_simd/tests/masks.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,19 @@ macro_rules! test_mask_api {
9999
assert_eq!(Mask::<$type, 2>::from_bitmask(bitmask), mask);
100100
}
101101

102+
#[cfg(feature = "all_lane_counts")]
103+
#[test]
104+
fn roundtrip_bitmask_conversion_odd() {
105+
let values = [
106+
true, false, true, false, true, true, false, false, false, true, true,
107+
];
108+
let mask = Mask::<$type, 11>::from_array(values);
109+
let bitmask = mask.to_bitmask();
110+
assert_eq!(bitmask, 0b11000110101);
111+
assert_eq!(Mask::<$type, 11>::from_bitmask(bitmask), mask);
112+
}
113+
114+
102115
#[test]
103116
fn cast() {
104117
fn cast_impl<T: core_simd::simd::MaskElement>()
@@ -134,6 +147,35 @@ macro_rules! test_mask_api {
134147
assert_eq!(bitmask.resize::<2>(0).to_ne_bytes()[..2], [0b01001001, 0b10000011]);
135148
assert_eq!(Mask::<$type, 16>::from_bitmask_vector(bitmask), mask);
136149
}
150+
151+
// rust-lang/portable-simd#379
152+
#[test]
153+
fn roundtrip_bitmask_vector_conversion_small() {
154+
use core_simd::simd::ToBytes;
155+
let values = [
156+
true, false, true, true
157+
];
158+
let mask = Mask::<$type, 4>::from_array(values);
159+
let bitmask = mask.to_bitmask_vector();
160+
assert_eq!(bitmask.resize::<1>(0).to_ne_bytes()[0], 0b00001101);
161+
assert_eq!(Mask::<$type, 4>::from_bitmask_vector(bitmask), mask);
162+
}
163+
164+
/* FIXME doesn't work with non-powers-of-two, yet
165+
// rust-lang/portable-simd#379
166+
#[cfg(feature = "all_lane_counts")]
167+
#[test]
168+
fn roundtrip_bitmask_vector_conversion_odd() {
169+
use core_simd::simd::ToBytes;
170+
let values = [
171+
true, false, true, false, true, true, false, false, false, true, true,
172+
];
173+
let mask = Mask::<$type, 11>::from_array(values);
174+
let bitmask = mask.to_bitmask_vector();
175+
assert_eq!(bitmask.resize::<2>(0).to_ne_bytes()[..2], [0b00110101, 0b00000110]);
176+
assert_eq!(Mask::<$type, 11>::from_bitmask_vector(bitmask), mask);
177+
}
178+
*/
137179
}
138180
}
139181
}

0 commit comments

Comments
 (0)