@@ -1923,15 +1923,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
1923
1923
v2 : RValue < ' gcc > ,
1924
1924
mask : RValue < ' gcc > ,
1925
1925
) -> RValue < ' gcc > {
1926
- let struct_type = mask. get_type ( ) . is_struct ( ) . expect ( "mask should be of struct type" ) ;
1927
-
1928
1926
// TODO(antoyo): use a recursive unqualified() here.
1929
1927
let vector_type = v1. get_type ( ) . unqualified ( ) . dyncast_vector ( ) . expect ( "vector type" ) ;
1930
1928
let element_type = vector_type. get_element_type ( ) ;
1931
1929
let vec_num_units = vector_type. get_num_units ( ) ;
1932
1930
1933
- let mask_num_units = struct_type. get_field_count ( ) ;
1934
- let mut vector_elements = vec ! [ ] ;
1935
1931
let mask_element_type = if element_type. is_integral ( ) {
1936
1932
element_type
1937
1933
} else {
@@ -1942,19 +1938,39 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
1942
1938
#[ cfg( not( feature = "master" ) ) ]
1943
1939
self . int_type
1944
1940
} ;
1945
- for i in 0 ..mask_num_units {
1946
- let field = struct_type. get_field ( i as i32 ) ;
1947
- vector_elements. push ( self . context . new_cast (
1948
- self . location ,
1949
- mask. access_field ( self . location , field) . to_rvalue ( ) ,
1950
- mask_element_type,
1951
- ) ) ;
1952
- }
1941
+
1942
+ let mut mask_elements = if let Some ( vector_type) = mask. get_type ( ) . dyncast_vector ( ) {
1943
+ let mask_num_units = vector_type. get_num_units ( ) ;
1944
+ let mut mask_elements = vec ! [ ] ;
1945
+ for i in 0 ..mask_num_units {
1946
+ let index = self . context . new_rvalue_from_long ( self . cx . type_u32 ( ) , i as _ ) ;
1947
+ mask_elements. push ( self . context . new_cast (
1948
+ self . location ,
1949
+ self . extract_element ( mask, index) . to_rvalue ( ) ,
1950
+ mask_element_type,
1951
+ ) ) ;
1952
+ }
1953
+ mask_elements
1954
+ } else {
1955
+ let struct_type = mask. get_type ( ) . is_struct ( ) . expect ( "mask should be of struct type" ) ;
1956
+ let mask_num_units = struct_type. get_field_count ( ) ;
1957
+ let mut mask_elements = vec ! [ ] ;
1958
+ for i in 0 ..mask_num_units {
1959
+ let field = struct_type. get_field ( i as i32 ) ;
1960
+ mask_elements. push ( self . context . new_cast (
1961
+ self . location ,
1962
+ mask. access_field ( self . location , field) . to_rvalue ( ) ,
1963
+ mask_element_type,
1964
+ ) ) ;
1965
+ }
1966
+ mask_elements
1967
+ } ;
1968
+ let mask_num_units = mask_elements. len ( ) ;
1953
1969
1954
1970
// NOTE: the mask needs to be the same length as the input vectors, so add the missing
1955
1971
// elements in the mask if needed.
1956
1972
for _ in mask_num_units..vec_num_units {
1957
- vector_elements . push ( self . context . new_rvalue_zero ( mask_element_type) ) ;
1973
+ mask_elements . push ( self . context . new_rvalue_zero ( mask_element_type) ) ;
1958
1974
}
1959
1975
1960
1976
let result_type = self . context . new_vector_type ( element_type, mask_num_units as u64 ) ;
@@ -1998,7 +2014,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
1998
2014
1999
2015
let new_mask_num_units = std:: cmp:: max ( mask_num_units, vec_num_units) ;
2000
2016
let mask_type = self . context . new_vector_type ( mask_element_type, new_mask_num_units as u64 ) ;
2001
- let mask = self . context . new_rvalue_from_vector ( self . location , mask_type, & vector_elements ) ;
2017
+ let mask = self . context . new_rvalue_from_vector ( self . location , mask_type, & mask_elements ) ;
2002
2018
let result = self . context . new_rvalue_vector_perm ( self . location , v1, v2, mask) ;
2003
2019
2004
2020
if vec_num_units != mask_num_units {
0 commit comments