@@ -1921,15 +1921,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
19211921 v2 : RValue < ' gcc > ,
19221922 mask : RValue < ' gcc > ,
19231923 ) -> RValue < ' gcc > {
1924- let struct_type = mask. get_type ( ) . is_struct ( ) . expect ( "mask should be of struct type" ) ;
1925-
19261924 // TODO(antoyo): use a recursive unqualified() here.
19271925 let vector_type = v1. get_type ( ) . unqualified ( ) . dyncast_vector ( ) . expect ( "vector type" ) ;
19281926 let element_type = vector_type. get_element_type ( ) ;
19291927 let vec_num_units = vector_type. get_num_units ( ) ;
19301928
1931- let mask_num_units = struct_type. get_field_count ( ) ;
1932- let mut vector_elements = vec ! [ ] ;
19331929 let mask_element_type = if element_type. is_integral ( ) {
19341930 element_type
19351931 } else {
@@ -1940,19 +1936,39 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
19401936 #[ cfg( not( feature = "master" ) ) ]
19411937 self . int_type
19421938 } ;
1943- for i in 0 ..mask_num_units {
1944- let field = struct_type. get_field ( i as i32 ) ;
1945- vector_elements. push ( self . context . new_cast (
1946- self . location ,
1947- mask. access_field ( self . location , field) . to_rvalue ( ) ,
1948- mask_element_type,
1949- ) ) ;
1950- }
1939+
1940+ let mut mask_elements = if let Some ( vector_type) = mask. get_type ( ) . dyncast_vector ( ) {
1941+ let mask_num_units = vector_type. get_num_units ( ) ;
1942+ let mut mask_elements = vec ! [ ] ;
1943+ for i in 0 ..mask_num_units {
1944+ let index = self . context . new_rvalue_from_long ( self . cx . type_u32 ( ) , i as _ ) ;
1945+ mask_elements. push ( self . context . new_cast (
1946+ self . location ,
1947+ self . extract_element ( mask, index) . to_rvalue ( ) ,
1948+ mask_element_type,
1949+ ) ) ;
1950+ }
1951+ mask_elements
1952+ } else {
1953+ let struct_type = mask. get_type ( ) . is_struct ( ) . expect ( "mask should be of struct type" ) ;
1954+ let mask_num_units = struct_type. get_field_count ( ) ;
1955+ let mut mask_elements = vec ! [ ] ;
1956+ for i in 0 ..mask_num_units {
1957+ let field = struct_type. get_field ( i as i32 ) ;
1958+ mask_elements. push ( self . context . new_cast (
1959+ self . location ,
1960+ mask. access_field ( self . location , field) . to_rvalue ( ) ,
1961+ mask_element_type,
1962+ ) ) ;
1963+ }
1964+ mask_elements
1965+ } ;
1966+ let mask_num_units = mask_elements. len ( ) ;
19511967
19521968 // NOTE: the mask needs to be the same length as the input vectors, so add the missing
19531969 // elements in the mask if needed.
19541970 for _ in mask_num_units..vec_num_units {
1955- vector_elements . push ( self . context . new_rvalue_zero ( mask_element_type) ) ;
1971+ mask_elements . push ( self . context . new_rvalue_zero ( mask_element_type) ) ;
19561972 }
19571973
19581974 let result_type = self . context . new_vector_type ( element_type, mask_num_units as u64 ) ;
@@ -1996,7 +2012,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
19962012
19972013 let new_mask_num_units = std:: cmp:: max ( mask_num_units, vec_num_units) ;
19982014 let mask_type = self . context . new_vector_type ( mask_element_type, new_mask_num_units as u64 ) ;
1999- let mask = self . context . new_rvalue_from_vector ( self . location , mask_type, & vector_elements ) ;
2015+ let mask = self . context . new_rvalue_from_vector ( self . location , mask_type, & mask_elements ) ;
20002016 let result = self . context . new_rvalue_vector_perm ( self . location , v1, v2, mask) ;
20012017
20022018 if vec_num_units != mask_num_units {
0 commit comments