diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index bd52a25551e..f89bbefba63 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -112,7 +112,18 @@ pub fn to_bitmask(self) -> U::BitMask { // TODO remove the transmute when rustc is more flexible assert_eq!(core::mem::size_of::(), core::mem::size_of::()); let mask: U::IntBitMask = crate::intrinsics::simd_bitmask(self.0); - core::mem::transmute_copy(&mask) + let mut bitmask: U::BitMask = core::mem::transmute_copy(&mask); + + // There is a bug where LLVM appears to implement this operation with the wrong + // bit order. + // TODO fix this in a better way + if cfg!(any(target_arch = "mips", target_arch = "mips64")) { + for x in bitmask.as_mut() { + *x = x.reverse_bits(); + } + } + + bitmask } } } diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs index 54427ec1ec0..7021d58aa54 100644 --- a/crates/core_simd/tests/masks.rs +++ b/crates/core_simd/tests/masks.rs @@ -70,10 +70,10 @@ fn roundtrip_int_conversion() { fn to_bitmask() { let values = [ true, false, false, true, false, false, true, false, - false, false, false, false, false, false, false, false, + true, true, false, false, false, false, false, true, ]; let mask = core_simd::$name::<16>::from_array(values); - assert_eq!(mask.to_bitmask(), [0b01001001, 0]); + assert_eq!(mask.to_bitmask(), [0b01001001, 0b10000011]); } } }