@@ -1923,15 +1923,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
19231923 v2 : RValue < ' gcc > ,
19241924 mask : RValue < ' gcc > ,
19251925 ) -> RValue < ' gcc > {
1926- let struct_type = mask. get_type ( ) . is_struct ( ) . expect ( "mask should be of struct type" ) ;
1927-
19281926 // TODO(antoyo): use a recursive unqualified() here.
19291927 let vector_type = v1. get_type ( ) . unqualified ( ) . dyncast_vector ( ) . expect ( "vector type" ) ;
19301928 let element_type = vector_type. get_element_type ( ) ;
19311929 let vec_num_units = vector_type. get_num_units ( ) ;
19321930
1933- let mask_num_units = struct_type. get_field_count ( ) ;
1934- let mut vector_elements = vec ! [ ] ;
19351931 let mask_element_type = if element_type. is_integral ( ) {
19361932 element_type
19371933 } else {
@@ -1942,19 +1938,39 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
19421938 #[ cfg( not( feature = "master" ) ) ]
19431939 self . int_type
19441940 } ;
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 ( ) ;
19531969
19541970 // NOTE: the mask needs to be the same length as the input vectors, so add the missing
19551971 // elements in the mask if needed.
19561972 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) ) ;
19581974 }
19591975
19601976 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> {
19982014
19992015 let new_mask_num_units = std:: cmp:: max ( mask_num_units, vec_num_units) ;
20002016 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 ) ;
20022018 let result = self . context . new_rvalue_vector_perm ( self . location , v1, v2, mask) ;
20032019
20042020 if vec_num_units != mask_num_units {
0 commit comments