Closed RalfJung closed 9 months ago
I am assuming that simd_select_bitmask is supposed to pass this testcase:
unsafe {
let selected1 = simd_select_bitmask::<u16, _>(
if cfg!(target_endian = "little") { 0b1010001101001001 } else { 0b1001001011000101 },
i32x16::splat(1), // yes
i32x16::splat(0), // no
);
let selected2 = simd_select_bitmask::<[u8; 2], _>(
if cfg!(target_endian = "little") {
[0b01001001, 0b10100011]
} else {
[0b10010010, 0b11000101]
},
i32x16::splat(1), // yes
i32x16::splat(0), // no
);
assert_eq!(selected1, i32x16::from_array([1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1]));
assert_eq!(selected2, selected1);
// Also try masks less than a byte long.
let selected1 = simd_select_bitmask::<u8, _>(
if cfg!(target_endian = "little") { 0b1000 } else { 0b0001 },
i32x4::splat(1), // yes
i32x4::splat(0), // no
);
let selected2 = simd_select_bitmask::<[u8; 1], _>(
if cfg!(target_endian = "little") { [0b1000] } else { [0b0001] },
i32x4::splat(1), // yes
i32x4::splat(0), // no
);
assert_eq!(selected1, i32x4::from_array([0, 0, 0, 1]));
assert_eq!(selected2, selected1);
}
That matches the testcase for simd_bitmask mentioned in https://github.com/rust-lang/portable-simd/pull/378.
This code, running on big-endian
ends up calling
simd_select_bitmask
with the mask being0b10110000
. I think that's wrong; for simd_bitmask the mask lives in the least-sigificant bits (see https://github.com/rust-lang/portable-simd/pull/378) so I would expect thatsimd_select_bitmask
should be called with0b00001011
.This issue is reminiscent of https://github.com/rust-lang/portable-simd/pull/267.