@@ -965,6 +965,20 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
965
965
} } ;
966
966
}
967
967
968
+ fn vector_mask_to_bitmask < ' a , ' ll , ' tcx > (
969
+ bx : & mut Builder < ' a , ' ll , ' tcx > ,
970
+ i_xn : & ' ll Value ,
971
+ in_elem_bitwidth : u64 ,
972
+ in_len : u64 ,
973
+ ) -> & ' ll Value {
974
+ // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position.
975
+ let shift_idx = bx. cx . const_int ( bx. type_ix ( in_elem_bitwidth) , ( in_elem_bitwidth - 1 ) as _ ) ;
976
+ let shift_indices = vec ! [ shift_idx; in_len as _] ;
977
+ let i_xn_msb = bx. lshr ( i_xn, bx. const_vector ( shift_indices. as_slice ( ) ) ) ;
978
+ // Truncate vector to an <i1 x N>
979
+ bx. trunc ( i_xn_msb, bx. type_vector ( bx. type_i1 ( ) , in_len) )
980
+ }
981
+
968
982
let tcx = bx. tcx ( ) ;
969
983
let sig =
970
984
tcx. normalize_erasing_late_bound_regions ( ty:: ParamEnv :: reveal_all ( ) , callee_ty. fn_sig ( tcx) ) ;
@@ -1225,14 +1239,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1225
1239
m_len == v_len,
1226
1240
InvalidMonomorphization :: MismatchedLengths { span, name, m_len, v_len }
1227
1241
) ;
1228
- match m_elem_ty. kind ( ) {
1229
- ty:: Int ( _ ) => { }
1242
+ let in_elem_bitwidth = match m_elem_ty. kind ( ) {
1243
+ ty:: Int ( i ) => i . bit_width ( ) . unwrap_or_else ( || bx . data_layout ( ) . pointer_size . bits ( ) ) ,
1230
1244
_ => return_error ! ( InvalidMonomorphization :: MaskType { span, name, ty: m_elem_ty } ) ,
1231
- }
1232
- // truncate the mask to a vector of i1s
1233
- let i1 = bx. type_i1 ( ) ;
1234
- let i1xn = bx. type_vector ( i1, m_len as u64 ) ;
1235
- let m_i1s = bx. trunc ( args[ 0 ] . immediate ( ) , i1xn) ;
1245
+ } ;
1246
+ let m_i1s = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , in_elem_bitwidth, m_len) ;
1236
1247
return Ok ( bx. select ( m_i1s, args[ 1 ] . immediate ( ) , args[ 2 ] . immediate ( ) ) ) ;
1237
1248
}
1238
1249
@@ -1267,15 +1278,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1267
1278
} ) ,
1268
1279
} ;
1269
1280
1270
- // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position.
1271
- let shift_indices =
1272
- vec ! [
1273
- bx. cx. const_int( bx. type_ix( in_elem_bitwidth) , ( in_elem_bitwidth - 1 ) as _) ;
1274
- in_len as _
1275
- ] ;
1276
- let i_xn_msb = bx. lshr ( i_xn, bx. const_vector ( shift_indices. as_slice ( ) ) ) ;
1277
- // Truncate vector to an <i1 x N>
1278
- let i1xn = bx. trunc ( i_xn_msb, bx. type_vector ( bx. type_i1 ( ) , in_len) ) ;
1281
+ let i1xn = vector_mask_to_bitmask ( bx, i_xn, in_elem_bitwidth, in_len) ;
1279
1282
// Bitcast <i1 x N> to iN:
1280
1283
let i_ = bx. bitcast ( i1xn, bx. type_ix ( in_len) ) ;
1281
1284
@@ -1493,28 +1496,25 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1493
1496
}
1494
1497
) ;
1495
1498
1496
- match element_ty2. kind ( ) {
1497
- ty:: Int ( _ ) => ( ) ,
1499
+ let mask_elem_bitwidth = match element_ty2. kind ( ) {
1500
+ ty:: Int ( i ) => i . bit_width ( ) . unwrap_or_else ( || bx . data_layout ( ) . pointer_size . bits ( ) ) ,
1498
1501
_ => {
1499
1502
return_error ! ( InvalidMonomorphization :: ThirdArgElementType {
1500
1503
span,
1501
1504
name,
1502
1505
expected_element: element_ty2,
1503
1506
third_arg: arg_tys[ 2 ]
1504
- } ) ;
1507
+ } )
1505
1508
}
1506
- }
1509
+ } ;
1507
1510
1508
1511
// Alignment of T, must be a constant integer value:
1509
1512
let alignment_ty = bx. type_i32 ( ) ;
1510
1513
let alignment = bx. const_i32 ( bx. align_of ( in_elem) . bytes ( ) as i32 ) ;
1511
1514
1512
1515
// Truncate the mask vector to a vector of i1s:
1513
- let ( mask, mask_ty) = {
1514
- let i1 = bx. type_i1 ( ) ;
1515
- let i1xn = bx. type_vector ( i1, in_len) ;
1516
- ( bx. trunc ( args[ 2 ] . immediate ( ) , i1xn) , i1xn)
1517
- } ;
1516
+ let mask = vector_mask_to_bitmask ( bx, args[ 2 ] . immediate ( ) , mask_elem_bitwidth, in_len) ;
1517
+ let mask_ty = bx. type_vector ( bx. type_i1 ( ) , in_len) ;
1518
1518
1519
1519
// Type of the vector of pointers:
1520
1520
let llvm_pointer_vec_ty = llvm_vector_ty ( bx, element_ty1, in_len) ;
@@ -1790,8 +1790,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1790
1790
) ;
1791
1791
1792
1792
// The element type of the third argument must be a signed integer type of any width:
1793
- match element_ty2. kind ( ) {
1794
- ty:: Int ( _ ) => ( ) ,
1793
+ let mask_elem_bitwidth = match element_ty2. kind ( ) {
1794
+ ty:: Int ( i ) => i . bit_width ( ) . unwrap_or_else ( || bx . data_layout ( ) . pointer_size . bits ( ) ) ,
1795
1795
_ => {
1796
1796
return_error ! ( InvalidMonomorphization :: ThirdArgElementType {
1797
1797
span,
@@ -1800,18 +1800,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1800
1800
third_arg: arg_tys[ 2 ]
1801
1801
} ) ;
1802
1802
}
1803
- }
1803
+ } ;
1804
1804
1805
1805
// Alignment of T, must be a constant integer value:
1806
1806
let alignment_ty = bx. type_i32 ( ) ;
1807
1807
let alignment = bx. const_i32 ( bx. align_of ( in_elem) . bytes ( ) as i32 ) ;
1808
1808
1809
1809
// Truncate the mask vector to a vector of i1s:
1810
- let ( mask, mask_ty) = {
1811
- let i1 = bx. type_i1 ( ) ;
1812
- let i1xn = bx. type_vector ( i1, in_len) ;
1813
- ( bx. trunc ( args[ 2 ] . immediate ( ) , i1xn) , i1xn)
1814
- } ;
1810
+ let mask = vector_mask_to_bitmask ( bx, args[ 2 ] . immediate ( ) , mask_elem_bitwidth, in_len) ;
1811
+ let mask_ty = bx. type_vector ( bx. type_i1 ( ) , in_len) ;
1815
1812
1816
1813
let ret_t = bx. type_void ( ) ;
1817
1814
@@ -1949,8 +1946,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1949
1946
) ;
1950
1947
args[ 0 ] . immediate( )
1951
1948
} else {
1952
- match in_elem. kind( ) {
1953
- ty:: Int ( _) | ty:: Uint ( _) => { }
1949
+ let bitwidth = match in_elem. kind( ) {
1950
+ ty:: Int ( i) => {
1951
+ i. bit_width( ) . unwrap_or_else( || bx. data_layout( ) . pointer_size. bits( ) )
1952
+ }
1953
+ ty:: Uint ( i) => {
1954
+ i. bit_width( ) . unwrap_or_else( || bx. data_layout( ) . pointer_size. bits( ) )
1955
+ }
1954
1956
_ => return_error!( InvalidMonomorphization :: UnsupportedSymbol {
1955
1957
span,
1956
1958
name,
@@ -1959,12 +1961,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1959
1961
in_elem,
1960
1962
ret_ty
1961
1963
} ) ,
1962
- }
1964
+ } ;
1963
1965
1964
- // boolean reductions operate on vectors of i1s:
1965
- let i1 = bx. type_i1( ) ;
1966
- let i1xn = bx. type_vector( i1, in_len as u64 ) ;
1967
- bx. trunc( args[ 0 ] . immediate( ) , i1xn)
1966
+ vector_mask_to_bitmask( bx, args[ 0 ] . immediate( ) , bitwidth, in_len as _)
1968
1967
} ;
1969
1968
return match in_elem. kind( ) {
1970
1969
ty:: Int ( _) | ty:: Uint ( _) => {
0 commit comments