@@ -1465,49 +1465,52 @@ fn simd_funnel_shift<'a, 'gcc, 'tcx>(
1465
1465
shift : RValue < ' gcc > ,
1466
1466
shift_left : bool ,
1467
1467
) -> RValue < ' gcc > {
1468
+ use crate :: common:: SignType ;
1469
+
1468
1470
let a_type = a. get_type ( ) ;
1469
1471
let vector_type = a_type. unqualified ( ) . dyncast_vector ( ) . expect ( "vector type" ) ;
1470
1472
let num_units = vector_type. get_num_units ( ) ;
1471
1473
let elem_type = vector_type. get_element_type ( ) ;
1472
1474
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
+ {
1474
1478
( 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
+ {
1476
1481
( 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
+ {
1478
1484
( 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
+ {
1480
1487
( 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 )
1489
1488
} else {
1490
1489
unimplemented ! ( "funnel shift on {:?}" , elem_type) ;
1491
1490
} ;
1492
1491
1493
1492
let int_mask = bx. context . new_rvalue_from_long ( new_int_type, int_mask as i64 ) ;
1494
1493
let int_shift_val = bx. context . new_rvalue_from_int ( new_int_type, int_shift_val) ;
1495
1494
let mut elements = vec ! [ ] ;
1495
+ let unsigned_type = elem_type. to_unsigned ( bx) ;
1496
1496
for i in 0 ..num_units {
1497
1497
let index = bx. context . new_rvalue_from_int ( bx. int_type , i as i32 ) ;
1498
1498
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) ;
1500
1502
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) ;
1502
1505
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) ;
1504
1507
let mut val = a_val << int_shift_val | b_val;
1505
1508
if shift_left {
1506
1509
val = ( val << shift_val) >> int_shift_val;
1507
1510
} else {
1508
1511
val = ( val >> shift_val) & int_mask;
1509
1512
}
1510
- let val = bx. context . new_cast ( None , val, elem_type) ;
1513
+ let val = bx. gcc_int_cast ( val, elem_type) ;
1511
1514
elements. push ( val) ;
1512
1515
}
1513
1516
bx. context . new_rvalue_from_vector ( None , a_type, & elements)
0 commit comments