@@ -1465,49 +1465,52 @@ fn simd_funnel_shift<'a, 'gcc, 'tcx>(
14651465 shift : RValue < ' gcc > ,
14661466 shift_left : bool ,
14671467) -> RValue < ' gcc > {
1468+ use crate :: common:: SignType ;
1469+
14681470 let a_type = a. get_type ( ) ;
14691471 let vector_type = a_type. unqualified ( ) . dyncast_vector ( ) . expect ( "vector type" ) ;
14701472 let num_units = vector_type. get_num_units ( ) ;
14711473 let elem_type = vector_type. get_element_type ( ) ;
14721474
1473- let ( new_int_type, int_shift_val, int_mask) = if elem_type. is_compatible_with ( bx. u8_type ) {
1475+ let ( new_int_type, int_shift_val, int_mask) = if elem_type. is_compatible_with ( bx. u8_type )
1476+ || elem_type. is_compatible_with ( bx. i8_type )
1477+ {
14741478 ( bx. u16_type , 8 , u8:: MAX as u64 )
1475- } else if elem_type. is_compatible_with ( bx. u16_type ) {
1479+ } else if elem_type. is_compatible_with ( bx. u16_type ) || elem_type. is_compatible_with ( bx. i16_type )
1480+ {
14761481 ( bx. u32_type , 16 , u16:: MAX as u64 )
1477- } else if elem_type. is_compatible_with ( bx. u32_type ) {
1482+ } else if elem_type. is_compatible_with ( bx. u32_type ) || elem_type. is_compatible_with ( bx. i32_type )
1483+ {
14781484 ( bx. u64_type , 32 , u32:: MAX as u64 )
1479- } else if elem_type. is_compatible_with ( bx. u64_type ) {
1485+ } else if elem_type. is_compatible_with ( bx. u64_type ) || elem_type. is_compatible_with ( bx. i64_type )
1486+ {
14801487 ( bx. u128_type , 64 , u64:: MAX )
1481- } else if elem_type. is_compatible_with ( bx. i8_type ) {
1482- ( bx. i16_type , 8 , u8:: MAX as u64 )
1483- } else if elem_type. is_compatible_with ( bx. i16_type ) {
1484- ( bx. i32_type , 16 , u16:: MAX as u64 )
1485- } else if elem_type. is_compatible_with ( bx. i32_type ) {
1486- ( bx. i64_type , 32 , u32:: MAX as u64 )
1487- } else if elem_type. is_compatible_with ( bx. i64_type ) {
1488- ( bx. i128_type , 64 , u64:: MAX )
14891488 } else {
14901489 unimplemented ! ( "funnel shift on {:?}" , elem_type) ;
14911490 } ;
14921491
14931492 let int_mask = bx. context . new_rvalue_from_long ( new_int_type, int_mask as i64 ) ;
14941493 let int_shift_val = bx. context . new_rvalue_from_int ( new_int_type, int_shift_val) ;
14951494 let mut elements = vec ! [ ] ;
1495+ let unsigned_type = elem_type. to_unsigned ( bx) ;
14961496 for i in 0 ..num_units {
14971497 let index = bx. context . new_rvalue_from_int ( bx. int_type , i as i32 ) ;
14981498 let a_val = bx. context . new_vector_access ( None , a, index) . to_rvalue ( ) ;
1499- let a_val = bx. context . new_cast ( None , a_val, new_int_type) ;
1499+ let a_val = bx. context . new_bitcast ( None , a_val, unsigned_type) ;
1500+ // TODO: we probably need to use gcc_int_cast instead.
1501+ let a_val = bx. gcc_int_cast ( a_val, new_int_type) ;
15001502 let b_val = bx. context . new_vector_access ( None , b, index) . to_rvalue ( ) ;
1501- let b_val = bx. context . new_cast ( None , b_val, new_int_type) ;
1503+ let b_val = bx. context . new_bitcast ( None , b_val, unsigned_type) ;
1504+ let b_val = bx. gcc_int_cast ( b_val, new_int_type) ;
15021505 let shift_val = bx. context . new_vector_access ( None , shift, index) . to_rvalue ( ) ;
1503- let shift_val = bx. context . new_cast ( None , shift_val, new_int_type) ;
1506+ let shift_val = bx. gcc_int_cast ( shift_val, new_int_type) ;
15041507 let mut val = a_val << int_shift_val | b_val;
15051508 if shift_left {
15061509 val = ( val << shift_val) >> int_shift_val;
15071510 } else {
15081511 val = ( val >> shift_val) & int_mask;
15091512 }
1510- let val = bx. context . new_cast ( None , val, elem_type) ;
1513+ let val = bx. gcc_int_cast ( val, elem_type) ;
15111514 elements. push ( val) ;
15121515 }
15131516 bx. context . new_rvalue_from_vector ( None , a_type, & elements)
0 commit comments