@@ -965,6 +965,33 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
965
965
} } ;
966
966
}
967
967
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
+
968
995
/// Converts a vector mask, where each element has a bit width equal to the data elements it is used with,
969
996
/// down to an i1 based mask that can be used by llvm intrinsics.
970
997
///
@@ -1252,10 +1279,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1252
1279
m_len == v_len,
1253
1280
InvalidMonomorphization :: MismatchedLengths { span, name, m_len, v_len }
1254
1281
) ;
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
+ ) ;
1259
1286
let m_i1s = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , in_elem_bitwidth, m_len) ;
1260
1287
return Ok ( bx. select ( m_i1s, args[ 1 ] . immediate ( ) , args[ 2 ] . immediate ( ) ) ) ;
1261
1288
}
@@ -1274,24 +1301,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1274
1301
let expected_bytes = expected_int_bits / 8 + ( ( expected_int_bits % 8 > 0 ) as u64 ) ;
1275
1302
1276
1303
// 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
+ ) ;
1293
1308
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) ;
1295
1310
// Bitcast <i1 x N> to iN:
1296
1311
let i_ = bx. bitcast ( i1xn, bx. type_ix ( in_len) ) ;
1297
1312
@@ -1509,17 +1524,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1509
1524
}
1510
1525
) ;
1511
1526
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 ]
1521
1534
}
1522
- } ;
1535
+ ) ;
1523
1536
1524
1537
// Alignment of T, must be a constant integer value:
1525
1538
let alignment_ty = bx. type_i32 ( ) ;
@@ -1612,8 +1625,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1612
1625
}
1613
1626
) ;
1614
1627
1615
- require ! (
1616
- matches! ( mask_elem. kind( ) , ty :: Int ( _ ) ) ,
1628
+ let m_elem_bitwidth = require_int_ty ! (
1629
+ mask_elem. kind( ) ,
1617
1630
InvalidMonomorphization :: ThirdArgElementType {
1618
1631
span,
1619
1632
name,
@@ -1622,17 +1635,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1622
1635
}
1623
1636
) ;
1624
1637
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
+
1625
1641
// Alignment of T, must be a constant integer value:
1626
1642
let alignment_ty = bx. type_i32 ( ) ;
1627
1643
let alignment = bx. const_i32 ( bx. align_of ( values_elem) . bytes ( ) as i32 ) ;
1628
1644
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
-
1636
1645
let llvm_pointer = bx. type_ptr ( ) ;
1637
1646
1638
1647
// Type of the vector of elements:
@@ -1704,8 +1713,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1704
1713
}
1705
1714
) ;
1706
1715
1707
- require ! (
1708
- matches! ( mask_elem. kind( ) , ty :: Int ( _ ) ) ,
1716
+ let m_elem_bitwidth = require_int_ty ! (
1717
+ mask_elem. kind( ) ,
1709
1718
InvalidMonomorphization :: ThirdArgElementType {
1710
1719
span,
1711
1720
name,
@@ -1714,17 +1723,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1714
1723
}
1715
1724
) ;
1716
1725
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
+
1717
1729
// Alignment of T, must be a constant integer value:
1718
1730
let alignment_ty = bx. type_i32 ( ) ;
1719
1731
let alignment = bx. const_i32 ( bx. align_of ( values_elem) . bytes ( ) as i32 ) ;
1720
1732
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
-
1728
1733
let ret_t = bx. type_void ( ) ;
1729
1734
1730
1735
let llvm_pointer = bx. type_ptr ( ) ;
@@ -1803,17 +1808,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1803
1808
) ;
1804
1809
1805
1810
// 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 ]
1815
1818
}
1816
- } ;
1819
+ ) ;
1817
1820
1818
1821
// Alignment of T, must be a constant integer value:
1819
1822
let alignment_ty = bx. type_i32 ( ) ;
0 commit comments