@@ -1829,10 +1829,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
18291829 }
18301830
18311831 if name == sym:: simd_masked_load {
1832- // simd_masked_load(mask: <N x i{M}>, pointer: *_ T, values: <N x T>) -> <N x T>
1832+ // simd_masked_load(mask: <N x i{M}>, pointer: *_ T, values: <N x T>, alignment: u32 ) -> <N x T>
18331833 // * N: number of elements in the input vectors
18341834 // * T: type of the element to load
18351835 // * M: any integer width is supported, will be truncated to i1
1836+ // * `alignment`: must be a power of two constant
18361837 // Loads contiguous elements from memory behind `pointer`, but only for
18371838 // those lanes whose `mask` bit is enabled.
18381839 // The memory addresses corresponding to the “off” lanes are not accessed.
@@ -1844,10 +1845,18 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
18441845 // The second argument must be a pointer matching the element type
18451846 let pointer_ty = args[ 1 ] . layout . ty ;
18461847
1847- // The last argument is a passthrough vector providing values for disabled lanes
1848+ // The third argument is a passthrough vector providing values for disabled lanes
18481849 let values_ty = args[ 2 ] . layout . ty ;
18491850 let ( values_len, values_elem) = require_simd ! ( values_ty, SimdThird ) ;
18501851
1852+ // The fourth argument is the alignment, must be a power of two integer constant
1853+ let alignment = bx
1854+ . const_to_opt_u128 ( args[ 3 ] . immediate ( ) , false )
1855+ . expect ( "typeck should have ensure that this is a const" ) ;
1856+ if !alignment. is_power_of_two ( ) {
1857+ return_error ! ( InvalidMonomorphization :: AlignmentNotPowerOfTwo { span, name } ) ;
1858+ }
1859+
18511860 require_simd ! ( ret_ty, SimdReturn ) ;
18521861
18531862 // Of the same length:
@@ -1893,7 +1902,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
18931902 let mask = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , m_elem_bitwidth, mask_len) ;
18941903
18951904 // Alignment of T, must be a constant integer value:
1896- let alignment = bx. const_i32 ( bx . align_of ( values_elem ) . bytes ( ) as i32 ) ;
1905+ let alignment = bx. const_i32 ( alignment as i32 ) ;
18971906
18981907 let llvm_pointer = bx. type_ptr ( ) ;
18991908
@@ -1908,10 +1917,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
19081917 }
19091918
19101919 if name == sym:: simd_masked_store {
1911- // simd_masked_store(mask: <N x i{M}>, pointer: *mut T, values: <N x T>) -> ()
1920+ // simd_masked_store(mask: <N x i{M}>, pointer: *mut T, values: <N x T>, alignment: u32 ) -> ()
19121921 // * N: number of elements in the input vectors
19131922 // * T: type of the element to load
19141923 // * M: any integer width is supported, will be truncated to i1
1924+ // * `alignment`: must be a power of two constant
19151925 // Stores contiguous elements to memory behind `pointer`, but only for
19161926 // those lanes whose `mask` bit is enabled.
19171927 // The memory addresses corresponding to the “off” lanes are not accessed.
@@ -1923,10 +1933,18 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
19231933 // The second argument must be a pointer matching the element type
19241934 let pointer_ty = args[ 1 ] . layout . ty ;
19251935
1926- // The last argument specifies the values to store to memory
1936+ // The third argument specifies the values to store to memory
19271937 let values_ty = args[ 2 ] . layout . ty ;
19281938 let ( values_len, values_elem) = require_simd ! ( values_ty, SimdThird ) ;
19291939
1940+ // The fourth argument is the alignment, must be a power of two integer constant
1941+ let alignment = bx
1942+ . const_to_opt_u128 ( args[ 3 ] . immediate ( ) , false )
1943+ . expect ( "typeck should have ensure that this is a const" ) ;
1944+ if !alignment. is_power_of_two ( ) {
1945+ return_error ! ( InvalidMonomorphization :: AlignmentNotPowerOfTwo { span, name } ) ;
1946+ }
1947+
19301948 // Of the same length:
19311949 require ! (
19321950 values_len == mask_len,
@@ -1965,8 +1983,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
19651983
19661984 let mask = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , m_elem_bitwidth, mask_len) ;
19671985
1968- // Alignment of T, must be a constant integer value:
1969- let alignment = bx. const_i32 ( bx. align_of ( values_elem) . bytes ( ) as i32 ) ;
1986+ let alignment = bx. const_i32 ( alignment as i32 ) ;
19701987
19711988 let llvm_pointer = bx. type_ptr ( ) ;
19721989
0 commit comments