@@ -1829,10 +1829,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1829
1829
}
1830
1830
1831
1831
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>
1833
1833
// * N: number of elements in the input vectors
1834
1834
// * T: type of the element to load
1835
1835
// * M: any integer width is supported, will be truncated to i1
1836
+ // * `alignment`: must be a power of two constant
1836
1837
// Loads contiguous elements from memory behind `pointer`, but only for
1837
1838
// those lanes whose `mask` bit is enabled.
1838
1839
// The memory addresses corresponding to the “off” lanes are not accessed.
@@ -1844,10 +1845,18 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1844
1845
// The second argument must be a pointer matching the element type
1845
1846
let pointer_ty = args[ 1 ] . layout . ty ;
1846
1847
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
1848
1849
let values_ty = args[ 2 ] . layout . ty ;
1849
1850
let ( values_len, values_elem) = require_simd ! ( values_ty, SimdThird ) ;
1850
1851
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
+
1851
1860
require_simd ! ( ret_ty, SimdReturn ) ;
1852
1861
1853
1862
// Of the same length:
@@ -1893,7 +1902,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1893
1902
let mask = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , m_elem_bitwidth, mask_len) ;
1894
1903
1895
1904
// 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 ) ;
1897
1906
1898
1907
let llvm_pointer = bx. type_ptr ( ) ;
1899
1908
@@ -1908,10 +1917,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1908
1917
}
1909
1918
1910
1919
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 ) -> ()
1912
1921
// * N: number of elements in the input vectors
1913
1922
// * T: type of the element to load
1914
1923
// * M: any integer width is supported, will be truncated to i1
1924
+ // * `alignment`: must be a power of two constant
1915
1925
// Stores contiguous elements to memory behind `pointer`, but only for
1916
1926
// those lanes whose `mask` bit is enabled.
1917
1927
// The memory addresses corresponding to the “off” lanes are not accessed.
@@ -1923,10 +1933,18 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1923
1933
// The second argument must be a pointer matching the element type
1924
1934
let pointer_ty = args[ 1 ] . layout . ty ;
1925
1935
1926
- // The last argument specifies the values to store to memory
1936
+ // The third argument specifies the values to store to memory
1927
1937
let values_ty = args[ 2 ] . layout . ty ;
1928
1938
let ( values_len, values_elem) = require_simd ! ( values_ty, SimdThird ) ;
1929
1939
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
+
1930
1948
// Of the same length:
1931
1949
require ! (
1932
1950
values_len == mask_len,
@@ -1965,8 +1983,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1965
1983
1966
1984
let mask = vector_mask_to_bitmask ( bx, args[ 0 ] . immediate ( ) , m_elem_bitwidth, mask_len) ;
1967
1985
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 ) ;
1970
1987
1971
1988
let llvm_pointer = bx. type_ptr ( ) ;
1972
1989
0 commit comments