about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAntoni Boucher <bouanto@zoho.com>2025-08-03 16:21:58 -0400
committerAntoni Boucher <bouanto@zoho.com>2025-08-03 16:21:58 -0400
commit566c9aeb66977f947f7b5a03d7e734c96625ca7f (patch)
treebe97a300c920b67add3f6171cd0e261bd4b17d7a
parent681651350f708260428b7b82621583f98c4d042f (diff)
downloadrust-566c9aeb66977f947f7b5a03d7e734c96625ca7f.tar.gz
rust-566c9aeb66977f947f7b5a03d7e734c96625ca7f.zip
Fix simd_funnel_shift
-rw-r--r--src/intrinsic/simd.rs35
1 files changed, 19 insertions, 16 deletions
diff --git a/src/intrinsic/simd.rs b/src/intrinsic/simd.rs
index 6748e1a4125..fdc15d580ef 100644
--- a/src/intrinsic/simd.rs
+++ b/src/intrinsic/simd.rs
@@ -1465,27 +1465,26 @@ fn simd_funnel_shift<'a, 'gcc, 'tcx>(
     shift: RValue<'gcc>,
     shift_left: bool,
 ) -> RValue<'gcc> {
+    use crate::common::SignType;
+
     let a_type = a.get_type();
     let vector_type = a_type.unqualified().dyncast_vector().expect("vector type");
     let num_units = vector_type.get_num_units();
     let elem_type = vector_type.get_element_type();
 
-    let (new_int_type, int_shift_val, int_mask) = if elem_type.is_compatible_with(bx.u8_type) {
+    let (new_int_type, int_shift_val, int_mask) = if elem_type.is_compatible_with(bx.u8_type)
+        || elem_type.is_compatible_with(bx.i8_type)
+    {
         (bx.u16_type, 8, u8::MAX as u64)
-    } else if elem_type.is_compatible_with(bx.u16_type) {
+    } else if elem_type.is_compatible_with(bx.u16_type) || elem_type.is_compatible_with(bx.i16_type)
+    {
         (bx.u32_type, 16, u16::MAX as u64)
-    } else if elem_type.is_compatible_with(bx.u32_type) {
+    } else if elem_type.is_compatible_with(bx.u32_type) || elem_type.is_compatible_with(bx.i32_type)
+    {
         (bx.u64_type, 32, u32::MAX as u64)
-    } else if elem_type.is_compatible_with(bx.u64_type) {
+    } else if elem_type.is_compatible_with(bx.u64_type) || elem_type.is_compatible_with(bx.i64_type)
+    {
         (bx.u128_type, 64, u64::MAX)
-    } else if elem_type.is_compatible_with(bx.i8_type) {
-        (bx.i16_type, 8, u8::MAX as u64)
-    } else if elem_type.is_compatible_with(bx.i16_type) {
-        (bx.i32_type, 16, u16::MAX as u64)
-    } else if elem_type.is_compatible_with(bx.i32_type) {
-        (bx.i64_type, 32, u32::MAX as u64)
-    } else if elem_type.is_compatible_with(bx.i64_type) {
-        (bx.i128_type, 64, u64::MAX)
     } else {
         unimplemented!("funnel shift on {:?}", elem_type);
     };
@@ -1493,21 +1492,25 @@ fn simd_funnel_shift<'a, 'gcc, 'tcx>(
     let int_mask = bx.context.new_rvalue_from_long(new_int_type, int_mask as i64);
     let int_shift_val = bx.context.new_rvalue_from_int(new_int_type, int_shift_val);
     let mut elements = vec![];
+    let unsigned_type = elem_type.to_unsigned(bx);
     for i in 0..num_units {
         let index = bx.context.new_rvalue_from_int(bx.int_type, i as i32);
         let a_val = bx.context.new_vector_access(None, a, index).to_rvalue();
-        let a_val = bx.context.new_cast(None, a_val, new_int_type);
+        let a_val = bx.context.new_bitcast(None, a_val, unsigned_type);
+        // TODO: we probably need to use gcc_int_cast instead.
+        let a_val = bx.gcc_int_cast(a_val, new_int_type);
         let b_val = bx.context.new_vector_access(None, b, index).to_rvalue();
-        let b_val = bx.context.new_cast(None, b_val, new_int_type);
+        let b_val = bx.context.new_bitcast(None, b_val, unsigned_type);
+        let b_val = bx.gcc_int_cast(b_val, new_int_type);
         let shift_val = bx.context.new_vector_access(None, shift, index).to_rvalue();
-        let shift_val = bx.context.new_cast(None, shift_val, new_int_type);
+        let shift_val = bx.gcc_int_cast(shift_val, new_int_type);
         let mut val = a_val << int_shift_val | b_val;
         if shift_left {
             val = (val << shift_val) >> int_shift_val;
         } else {
             val = (val >> shift_val) & int_mask;
         }
-        let val = bx.context.new_cast(None, val, elem_type);
+        let val = bx.gcc_int_cast(val, elem_type);
         elements.push(val);
     }
     bx.context.new_rvalue_from_vector(None, a_type, &elements)