Skip to content

Commit 0962ef9

Browse files
committed
attempt at making the GCC backend compatible with vector shuffle indices
1 parent 4e2b841 commit 0962ef9

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
@@ -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

Comments
 (0)