@@ -854,6 +854,20 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
854
854
} ;
855
855
}
856
856
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
+
857
871
let tcx = bx. tcx ( ) ;
858
872
let sig =
859
873
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>(
1061
1075
m_len == v_len,
1062
1076
InvalidMonomorphization :: MismatchedLengths { span, name, m_len, v_len }
1063
1077
) ;
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 ( ) ) ,
1066
1080
_ => 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) ;
1072
1083
return Ok ( bx. select ( m_i1s, args[ 1 ] . immediate ( ) , args[ 2 ] . immediate ( ) ) ) ;
1073
1084
}
1074
1085
@@ -1103,15 +1114,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1103
1114
} ) ,
1104
1115
} ;
1105
1116
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) ;
1115
1118
// Bitcast <i1 x N> to iN:
1116
1119
let i_ = bx. bitcast ( i1xn, bx. type_ix ( in_len) ) ;
1117
1120
@@ -1377,31 +1380,25 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1377
1380
1378
1381
// The element type of the third argument must be a signed integer type of any width:
1379
1382
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 ( ) ) ,
1382
1385
_ => {
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
+ } )
1392
1392
}
1393
- }
1393
+ } ;
1394
1394
1395
1395
// Alignment of T, must be a constant integer value:
1396
1396
let alignment_ty = bx. type_i32 ( ) ;
1397
1397
let alignment = bx. const_i32 ( bx. align_of ( in_elem) . bytes ( ) as i32 ) ;
1398
1398
1399
1399
// 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) ;
1405
1402
1406
1403
// Type of the vector of pointers:
1407
1404
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>(
1518
1515
assert_eq ! ( underlying_ty, non_ptr( element_ty0) ) ;
1519
1516
1520
1517
// 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 ( ) ) ,
1523
1520
_ => {
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
+ } ) ;
1533
1527
}
1534
- }
1528
+ } ;
1535
1529
1536
1530
// Alignment of T, must be a constant integer value:
1537
1531
let alignment_ty = bx. type_i32 ( ) ;
1538
1532
let alignment = bx. const_i32 ( bx. align_of ( in_elem) . bytes ( ) as i32 ) ;
1539
1533
1540
1534
// 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) ;
1546
1537
1547
1538
let ret_t = bx. type_void ( ) ;
1548
1539
@@ -1682,8 +1673,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1682
1673
) ;
1683
1674
args[ 0 ] . immediate( )
1684
1675
} 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
+ }
1687
1683
_ => return_error!( InvalidMonomorphization :: UnsupportedSymbol {
1688
1684
span,
1689
1685
name,
@@ -1692,12 +1688,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1692
1688
in_elem,
1693
1689
ret_ty
1694
1690
} ) ,
1695
- }
1691
+ } ;
1696
1692
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 _)
1701
1694
} ;
1702
1695
return match in_elem. kind( ) {
1703
1696
ty:: Int ( _) | ty:: Uint ( _) => {
0 commit comments