about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2024-02-19 12:33:08 +0100
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2024-02-19 12:33:08 +0100
commitb886be124d5bcbc242cb1f6f6a29c9fbaa577272 (patch)
treeeb7b9ac7e2ce54ed8484c76c8b57b66b0ddcf5b0
parente4584e84d9a4687bedf1481b60c1751a2478967c (diff)
downloadrust-b886be124d5bcbc242cb1f6f6a29c9fbaa577272.tar.gz
rust-b886be124d5bcbc242cb1f6f6a29c9fbaa577272.zip
Fix simd_select_bitmask on big-endian systems
The mask input for simd_select_bitmask depends on the host byteorder
in the same way as the mask output of simd_bitmask does.  Fix the
implementation to work on both big- and little-endian systems.
-rw-r--r--src/intrinsics/simd.rs8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs
index ebdc744bcd8..a5490bd091b 100644
--- a/src/intrinsics/simd.rs
+++ b/src/intrinsics/simd.rs
@@ -853,7 +853,13 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
             };
 
             for lane in 0..lane_count {
-                let m_lane = fx.bcx.ins().ushr_imm(m, u64::from(lane) as i64);
+                // The bit order of the mask depends on the byte endianness, LSB-first for
+                // little endian and MSB-first for big endian.
+                let mask_lane = match fx.tcx.sess.target.endian {
+                    Endian::Big => lane_count - 1 - lane,
+                    Endian::Little => lane,
+                };
+                let m_lane = fx.bcx.ins().ushr_imm(m, u64::from(mask_lane) as i64);
                 let m_lane = fx.bcx.ins().band_imm(m_lane, 1);
                 let a_lane = a.value_lane(fx, lane).load_scalar(fx);
                 let b_lane = b.value_lane(fx, lane).load_scalar(fx);