@@ -854,6 +854,20 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
854854 } ;
855855 }
856856
857+ fn vector_mask_to_bitmask < ' a , ' ll , ' tcx > (
858+ bx : & mut Builder < ' a , ' ll , ' tcx > ,
859+ i_xn : & ' ll Value ,
860+ in_elem_bitwidth : u64 ,
861+ in_len : u64 ,
862+ ) -> & ' ll Value {
863+ // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position.
864+ let shift_idx = bx. cx . const_int ( bx. type_ix ( in_elem_bitwidth) , ( in_elem_bitwidth - 1 ) as _ ) ;
865+ let shift_indices = vec ! [ shift_idx; in_len as _] ;
866+ let i_xn_msb = bx. lshr ( i_xn, bx. const_vector ( shift_indices. as_slice ( ) ) ) ;
867+ // Truncate vector to an <i1 x N>
868+ bx. trunc ( i_xn_msb, bx. type_vector ( bx. type_i1 ( ) , in_len) )
869+ }
870+
857871 let tcx = bx. tcx ( ) ;
858872 let sig =
859873 tcx. normalize_erasing_late_bound_regions ( ty:: ParamEnv :: reveal_all ( ) , callee_ty. fn_sig ( tcx) ) ;
@@ -1061,14 +1075,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
10611075 m_len == v_len,
10621076 InvalidMonomorphization :: MismatchedLengths { span, name, m_len, v_len }
10631077 ) ;
1064- match m_elem_ty. kind ( ) {
1065- ty:: Int ( _ ) => { }
1078+ let in_elem_bitwidth = match m_elem_ty. kind ( ) {
1079+ ty:: Int ( i ) => i . bit_width ( ) . unwrap_or_else ( || bx . data_layout ( ) . pointer_size . bits ( ) ) ,
10661080 _ => return_error ! ( InvalidMonomorphization :: MaskType { span, name, ty: m_elem_ty } ) ,
1067- }
1068- // truncate the mask to a vector of i1s
1069- let i1 = bx. type_i1 ( ) ;
1070- let i1xn = bx. type_vector ( i1, m_len as u64 ) ;
1071- let m_i1s = bx. trunc ( args[ 0 ] . immediate ( ) , i1xn) ;
1081+ } ;
1082+ let m_i1s = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , in_elem_bitwidth, m_len) ;
10721083 return Ok ( bx. select ( m_i1s, args[ 1 ] . immediate ( ) , args[ 2 ] . immediate ( ) ) ) ;
10731084 }
10741085
@@ -1103,15 +1114,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
11031114 } ) ,
11041115 } ;
11051116
1106- // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position.
1107- let shift_indices =
1108- vec ! [
1109- bx. cx. const_int( bx. type_ix( in_elem_bitwidth) , ( in_elem_bitwidth - 1 ) as _) ;
1110- in_len as _
1111- ] ;
1112- let i_xn_msb = bx. lshr ( i_xn, bx. const_vector ( shift_indices. as_slice ( ) ) ) ;
1113- // Truncate vector to an <i1 x N>
1114- let i1xn = bx. trunc ( i_xn_msb, bx. type_vector ( bx. type_i1 ( ) , in_len) ) ;
1117+ let i1xn = vector_mask_to_bitmask ( bx, i_xn, in_elem_bitwidth, in_len) ;
11151118 // Bitcast <i1 x N> to iN:
11161119 let i_ = bx. bitcast ( i1xn, bx. type_ix ( in_len) ) ;
11171120
@@ -1377,31 +1380,25 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
13771380
13781381 // The element type of the third argument must be a signed integer type of any width:
13791382 let ( _, element_ty2) = arg_tys[ 2 ] . simd_size_and_type ( bx. tcx ( ) ) ;
1380- match element_ty2. kind ( ) {
1381- ty:: Int ( _ ) => ( ) ,
1383+ let mask_elem_bitwidth = match element_ty2. kind ( ) {
1384+ ty:: Int ( i ) => i . bit_width ( ) . unwrap_or_else ( || bx . data_layout ( ) . pointer_size . bits ( ) ) ,
13821385 _ => {
1383- require ! (
1384- false ,
1385- InvalidMonomorphization :: ThirdArgElementType {
1386- span,
1387- name,
1388- expected_element: element_ty2,
1389- third_arg: arg_tys[ 2 ]
1390- }
1391- ) ;
1386+ return_error ! ( InvalidMonomorphization :: ThirdArgElementType {
1387+ span,
1388+ name,
1389+ expected_element: element_ty2,
1390+ third_arg: arg_tys[ 2 ]
1391+ } )
13921392 }
1393- }
1393+ } ;
13941394
13951395 // Alignment of T, must be a constant integer value:
13961396 let alignment_ty = bx. type_i32 ( ) ;
13971397 let alignment = bx. const_i32 ( bx. align_of ( in_elem) . bytes ( ) as i32 ) ;
13981398
13991399 // Truncate the mask vector to a vector of i1s:
1400- let ( mask, mask_ty) = {
1401- let i1 = bx. type_i1 ( ) ;
1402- let i1xn = bx. type_vector ( i1, in_len) ;
1403- ( bx. trunc ( args[ 2 ] . immediate ( ) , i1xn) , i1xn)
1404- } ;
1400+ let mask = vector_mask_to_bitmask ( bx, args[ 2 ] . immediate ( ) , mask_elem_bitwidth, in_len) ;
1401+ let mask_ty = bx. type_vector ( bx. type_i1 ( ) , in_len) ;
14051402
14061403 // Type of the vector of pointers:
14071404 let llvm_pointer_vec_ty = llvm_vector_ty ( bx, underlying_ty, in_len, pointer_count) ;
@@ -1518,31 +1515,25 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15181515 assert_eq ! ( underlying_ty, non_ptr( element_ty0) ) ;
15191516
15201517 // The element type of the third argument must be a signed integer type of any width:
1521- match element_ty2. kind ( ) {
1522- ty:: Int ( _ ) => ( ) ,
1518+ let mask_elem_bitwidth = match element_ty2. kind ( ) {
1519+ ty:: Int ( i ) => i . bit_width ( ) . unwrap_or_else ( || bx . data_layout ( ) . pointer_size . bits ( ) ) ,
15231520 _ => {
1524- require ! (
1525- false ,
1526- InvalidMonomorphization :: ThirdArgElementType {
1527- span,
1528- name,
1529- expected_element: element_ty2,
1530- third_arg: arg_tys[ 2 ]
1531- }
1532- ) ;
1521+ return_error ! ( InvalidMonomorphization :: ThirdArgElementType {
1522+ span,
1523+ name,
1524+ expected_element: element_ty2,
1525+ third_arg: arg_tys[ 2 ]
1526+ } ) ;
15331527 }
1534- }
1528+ } ;
15351529
15361530 // Alignment of T, must be a constant integer value:
15371531 let alignment_ty = bx. type_i32 ( ) ;
15381532 let alignment = bx. const_i32 ( bx. align_of ( in_elem) . bytes ( ) as i32 ) ;
15391533
15401534 // Truncate the mask vector to a vector of i1s:
1541- let ( mask, mask_ty) = {
1542- let i1 = bx. type_i1 ( ) ;
1543- let i1xn = bx. type_vector ( i1, in_len) ;
1544- ( bx. trunc ( args[ 2 ] . immediate ( ) , i1xn) , i1xn)
1545- } ;
1535+ let mask = vector_mask_to_bitmask ( bx, args[ 2 ] . immediate ( ) , mask_elem_bitwidth, in_len) ;
1536+ let mask_ty = bx. type_vector ( bx. type_i1 ( ) , in_len) ;
15461537
15471538 let ret_t = bx. type_void ( ) ;
15481539
@@ -1682,8 +1673,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16821673 ) ;
16831674 args[ 0 ] . immediate( )
16841675 } else {
1685- match in_elem. kind( ) {
1686- ty:: Int ( _) | ty:: Uint ( _) => { }
1676+ let bitwidth = match in_elem. kind( ) {
1677+ ty:: Int ( i) => {
1678+ i. bit_width( ) . unwrap_or_else( || bx. data_layout( ) . pointer_size. bits( ) )
1679+ }
1680+ ty:: Uint ( i) => {
1681+ i. bit_width( ) . unwrap_or_else( || bx. data_layout( ) . pointer_size. bits( ) )
1682+ }
16871683 _ => return_error!( InvalidMonomorphization :: UnsupportedSymbol {
16881684 span,
16891685 name,
@@ -1692,12 +1688,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16921688 in_elem,
16931689 ret_ty
16941690 } ) ,
1695- }
1691+ } ;
16961692
1697- // boolean reductions operate on vectors of i1s:
1698- let i1 = bx. type_i1( ) ;
1699- let i1xn = bx. type_vector( i1, in_len as u64 ) ;
1700- bx. trunc( args[ 0 ] . immediate( ) , i1xn)
1693+ vector_mask_to_bitmask( bx, args[ 0 ] . immediate( ) , bitwidth, in_len as _)
17011694 } ;
17021695 return match in_elem. kind( ) {
17031696 ty:: Int ( _) | ty:: Uint ( _) => {
0 commit comments