@@ -1921,15 +1921,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
1921
1921
v2 : RValue < ' gcc > ,
1922
1922
mask : RValue < ' gcc > ,
1923
1923
) -> RValue < ' gcc > {
1924
- let struct_type = mask. get_type ( ) . is_struct ( ) . expect ( "mask should be of struct type" ) ;
1925
-
1926
1924
// TODO(antoyo): use a recursive unqualified() here.
1927
1925
let vector_type = v1. get_type ( ) . unqualified ( ) . dyncast_vector ( ) . expect ( "vector type" ) ;
1928
1926
let element_type = vector_type. get_element_type ( ) ;
1929
1927
let vec_num_units = vector_type. get_num_units ( ) ;
1930
1928
1931
- let mask_num_units = struct_type. get_field_count ( ) ;
1932
- let mut vector_elements = vec ! [ ] ;
1933
1929
let mask_element_type = if element_type. is_integral ( ) {
1934
1930
element_type
1935
1931
} else {
@@ -1940,19 +1936,39 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
1940
1936
#[ cfg( not( feature = "master" ) ) ]
1941
1937
self . int_type
1942
1938
} ;
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 ( ) ;
1951
1967
1952
1968
// NOTE: the mask needs to be the same length as the input vectors, so add the missing
1953
1969
// elements in the mask if needed.
1954
1970
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) ) ;
1956
1972
}
1957
1973
1958
1974
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> {
1996
2012
1997
2013
let new_mask_num_units = std:: cmp:: max ( mask_num_units, vec_num_units) ;
1998
2014
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 ) ;
2000
2016
let result = self . context . new_rvalue_vector_perm ( self . location , v1, v2, mask) ;
2001
2017
2002
2018
if vec_num_units != mask_num_units {
0 commit comments