Skip to content

Commit daedbd4

Browse files
committed
make the GCC backend compatible with vector shuffle indices
1 parent 194baa8 commit daedbd4

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

compiler/rustc_codegen_gcc/src/builder.rs

+30-14
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)