@@ -965,6 +965,33 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
965965 } } ;
966966 }
967967
968+ /// Returns the bitwidth of the `$ty` argument if it is an `Int` type.
969+ macro_rules! require_int_ty {
970+ ( $ty: expr, $diag: expr) => {
971+ match $ty {
972+ ty:: Int ( i) => i. bit_width( ) . unwrap_or_else( || bx. data_layout( ) . pointer_size. bits( ) ) ,
973+ _ => {
974+ return_error!( $diag) ;
975+ }
976+ }
977+ } ;
978+ }
979+
980+ /// Returns the bitwidth of the `$ty` argument if it is an `Int` or `Uint` type.
981+ macro_rules! require_int_or_uint_ty {
982+ ( $ty: expr, $diag: expr) => {
983+ match $ty {
984+ ty:: Int ( i) => i. bit_width( ) . unwrap_or_else( || bx. data_layout( ) . pointer_size. bits( ) ) ,
985+ ty:: Uint ( i) => {
986+ i. bit_width( ) . unwrap_or_else( || bx. data_layout( ) . pointer_size. bits( ) )
987+ }
988+ _ => {
989+ return_error!( $diag) ;
990+ }
991+ }
992+ } ;
993+ }
994+
968995 /// Converts a vector mask, where each element has a bit width equal to the data elements it is used with,
969996 /// down to an i1 based mask that can be used by llvm intrinsics.
970997 ///
@@ -1252,10 +1279,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
12521279 m_len == v_len,
12531280 InvalidMonomorphization :: MismatchedLengths { span, name, m_len, v_len }
12541281 ) ;
1255- let in_elem_bitwidth = match m_elem_ty . kind ( ) {
1256- ty :: Int ( i ) => i . bit_width ( ) . unwrap_or_else ( || bx . data_layout ( ) . pointer_size . bits ( ) ) ,
1257- _ => return_error ! ( InvalidMonomorphization :: MaskType { span, name, ty: m_elem_ty } ) ,
1258- } ;
1282+ let in_elem_bitwidth = require_int_ty ! (
1283+ m_elem_ty . kind ( ) ,
1284+ InvalidMonomorphization :: MaskType { span, name, ty: m_elem_ty }
1285+ ) ;
12591286 let m_i1s = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , in_elem_bitwidth, m_len) ;
12601287 return Ok ( bx. select ( m_i1s, args[ 1 ] . immediate ( ) , args[ 2 ] . immediate ( ) ) ) ;
12611288 }
@@ -1274,24 +1301,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
12741301 let expected_bytes = expected_int_bits / 8 + ( ( expected_int_bits % 8 > 0 ) as u64 ) ;
12751302
12761303 // Integer vector <i{in_bitwidth} x in_len>:
1277- let ( i_xn, in_elem_bitwidth) = match in_elem. kind ( ) {
1278- ty:: Int ( i) => (
1279- args[ 0 ] . immediate ( ) ,
1280- i. bit_width ( ) . unwrap_or_else ( || bx. data_layout ( ) . pointer_size . bits ( ) ) ,
1281- ) ,
1282- ty:: Uint ( i) => (
1283- args[ 0 ] . immediate ( ) ,
1284- i. bit_width ( ) . unwrap_or_else ( || bx. data_layout ( ) . pointer_size . bits ( ) ) ,
1285- ) ,
1286- _ => return_error ! ( InvalidMonomorphization :: VectorArgument {
1287- span,
1288- name,
1289- in_ty,
1290- in_elem
1291- } ) ,
1292- } ;
1304+ let in_elem_bitwidth = require_int_or_uint_ty ! (
1305+ in_elem. kind( ) ,
1306+ InvalidMonomorphization :: VectorArgument { span, name, in_ty, in_elem }
1307+ ) ;
12931308
1294- let i1xn = vector_mask_to_bitmask ( bx, i_xn , in_elem_bitwidth, in_len) ;
1309+ let i1xn = vector_mask_to_bitmask ( bx, args [ 0 ] . immediate ( ) , in_elem_bitwidth, in_len) ;
12951310 // Bitcast <i1 x N> to iN:
12961311 let i_ = bx. bitcast ( i1xn, bx. type_ix ( in_len) ) ;
12971312
@@ -1509,17 +1524,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15091524 }
15101525 ) ;
15111526
1512- let mask_elem_bitwidth = match element_ty2. kind ( ) {
1513- ty:: Int ( i) => i. bit_width ( ) . unwrap_or_else ( || bx. data_layout ( ) . pointer_size . bits ( ) ) ,
1514- _ => {
1515- return_error ! ( InvalidMonomorphization :: ThirdArgElementType {
1516- span,
1517- name,
1518- expected_element: element_ty2,
1519- third_arg: arg_tys[ 2 ]
1520- } )
1527+ let mask_elem_bitwidth = require_int_ty ! (
1528+ element_ty2. kind( ) ,
1529+ InvalidMonomorphization :: ThirdArgElementType {
1530+ span,
1531+ name,
1532+ expected_element: element_ty2,
1533+ third_arg: arg_tys[ 2 ]
15211534 }
1522- } ;
1535+ ) ;
15231536
15241537 // Alignment of T, must be a constant integer value:
15251538 let alignment_ty = bx. type_i32 ( ) ;
@@ -1612,8 +1625,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16121625 }
16131626 ) ;
16141627
1615- require ! (
1616- matches! ( mask_elem. kind( ) , ty :: Int ( _ ) ) ,
1628+ let m_elem_bitwidth = require_int_ty ! (
1629+ mask_elem. kind( ) ,
16171630 InvalidMonomorphization :: ThirdArgElementType {
16181631 span,
16191632 name,
@@ -1622,17 +1635,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
16221635 }
16231636 ) ;
16241637
1638+ let mask = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , m_elem_bitwidth, mask_len) ;
1639+ let mask_ty = bx. type_vector ( bx. type_i1 ( ) , mask_len) ;
1640+
16251641 // Alignment of T, must be a constant integer value:
16261642 let alignment_ty = bx. type_i32 ( ) ;
16271643 let alignment = bx. const_i32 ( bx. align_of ( values_elem) . bytes ( ) as i32 ) ;
16281644
1629- // Truncate the mask vector to a vector of i1s:
1630- let ( mask, mask_ty) = {
1631- let i1 = bx. type_i1 ( ) ;
1632- let i1xn = bx. type_vector ( i1, mask_len) ;
1633- ( bx. trunc ( args[ 0 ] . immediate ( ) , i1xn) , i1xn)
1634- } ;
1635-
16361645 let llvm_pointer = bx. type_ptr ( ) ;
16371646
16381647 // Type of the vector of elements:
@@ -1704,8 +1713,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
17041713 }
17051714 ) ;
17061715
1707- require ! (
1708- matches! ( mask_elem. kind( ) , ty :: Int ( _ ) ) ,
1716+ let m_elem_bitwidth = require_int_ty ! (
1717+ mask_elem. kind( ) ,
17091718 InvalidMonomorphization :: ThirdArgElementType {
17101719 span,
17111720 name,
@@ -1714,17 +1723,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
17141723 }
17151724 ) ;
17161725
1726+ let mask = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , m_elem_bitwidth, mask_len) ;
1727+ let mask_ty = bx. type_vector ( bx. type_i1 ( ) , mask_len) ;
1728+
17171729 // Alignment of T, must be a constant integer value:
17181730 let alignment_ty = bx. type_i32 ( ) ;
17191731 let alignment = bx. const_i32 ( bx. align_of ( values_elem) . bytes ( ) as i32 ) ;
17201732
1721- // Truncate the mask vector to a vector of i1s:
1722- let ( mask, mask_ty) = {
1723- let i1 = bx. type_i1 ( ) ;
1724- let i1xn = bx. type_vector ( i1, in_len) ;
1725- ( bx. trunc ( args[ 0 ] . immediate ( ) , i1xn) , i1xn)
1726- } ;
1727-
17281733 let ret_t = bx. type_void ( ) ;
17291734
17301735 let llvm_pointer = bx. type_ptr ( ) ;
@@ -1803,17 +1808,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
18031808 ) ;
18041809
18051810 // The element type of the third argument must be a signed integer type of any width:
1806- let mask_elem_bitwidth = match element_ty2. kind ( ) {
1807- ty:: Int ( i) => i. bit_width ( ) . unwrap_or_else ( || bx. data_layout ( ) . pointer_size . bits ( ) ) ,
1808- _ => {
1809- return_error ! ( InvalidMonomorphization :: ThirdArgElementType {
1810- span,
1811- name,
1812- expected_element: element_ty2,
1813- third_arg: arg_tys[ 2 ]
1814- } ) ;
1811+ let mask_elem_bitwidth = require_int_ty ! (
1812+ element_ty2. kind( ) ,
1813+ InvalidMonomorphization :: ThirdArgElementType {
1814+ span,
1815+ name,
1816+ expected_element: element_ty2,
1817+ third_arg: arg_tys[ 2 ]
18151818 }
1816- } ;
1819+ ) ;
18171820
18181821 // Alignment of T, must be a constant integer value:
18191822 let alignment_ty = bx. type_i32 ( ) ;
0 commit comments