https://gcc.gnu.org/g:4d9b51c8cb13177913bb1bf8dac73b9d1d5db015
commit r17-4130-g4d9b51c8cb13177913bb1bf8dac73b9d1d5db015 Author: Philip Herron <[email protected]> Date: Mon Aug 17 20:58:59 2026 +0100 gccrs: Support repr simd to setup a gcc vector type GCC makes this stuff really straight forward which is nice. Fixes Rust-GCC/gccrs#4794 gcc/rust/ChangeLog: * backend/rust-compile-type.cc (TyTyResolveCompile::visit): make vector * rust-gcc.cc (struct_field_expression): we use bit field acces for lanes (constructor_expression): special case VECTOR (convert_tree): likewise for canonical main variant gcc/testsuite/ChangeLog: * rust/compile/issue-4794.rs: New test. Signed-off-by: Philip Herron <[email protected]> Diff: --- gcc/rust/backend/rust-compile-type.cc | 8 ++++++- gcc/rust/rust-gcc.cc | 40 +++++++++++++++++++++++++++++++- gcc/testsuite/rust/compile/issue-4794.rs | 35 ++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc index c3fb34260ee3..1a815b9ffebf 100644 --- a/gcc/rust/backend/rust-compile-type.cc +++ b/gcc/rust/backend/rust-compile-type.cc @@ -334,8 +334,14 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type) } } } + else if (repr.repr_kind == TyTy::ADTType::ReprKind::SIMD) + { + TyTy::VariantDef &variant = *type.get_variants ().at (0); + auto element = variant.get_fields ().at (0)->get_field_type (); + auto inner_type = compile (ctx, element); - // compilation of non-transparent ADTs below + type_record = build_vector_type (inner_type, variant.num_fields ()); + } else if (!type.is_enum ()) { rust_assert (type.number_of_variants () == 1); diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index 00f35638144e..ada66a2c7c6b 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -888,6 +888,18 @@ struct_field_expression (tree struct_tree, size_t index, location_t location) { if (error_operand_p (struct_tree)) return error_mark_node; + + if (VECTOR_TYPE_P (TREE_TYPE (struct_tree))) + { + tree vec_type = TREE_TYPE (struct_tree); + tree element_type = TREE_TYPE (vec_type); + tree part_width = TYPE_SIZE (element_type); + tree bit_offset = bitsize_int (index * tree_to_uhwi (part_width)); + + return fold_build3_loc (location, BIT_FIELD_REF, element_type, + struct_tree, part_width, bit_offset); + } + gcc_assert (TREE_CODE (TREE_TYPE (struct_tree)) == RECORD_TYPE || TREE_CODE (TREE_TYPE (struct_tree)) == UNION_TYPE); tree field = TYPE_FIELDS (TREE_TYPE (struct_tree)); @@ -1277,6 +1289,32 @@ constructor_expression (tree type_tree, bool is_variant, vec<constructor_elt, va_gc> *init; vec_alloc (init, union_index != -1 ? 1 : vals.size ()); + if (VECTOR_TYPE_P (type_tree)) + { + tree element_type = TREE_TYPE (type_tree); + bool is_constant = true; + for (size_t i = 0; i < vals.size (); ++i) + { + tree val = vals[i]; + if (error_operand_p (val)) + return error_mark_node; + + constructor_elt empty = {NULL, NULL}; + constructor_elt *elt = init->quick_push (empty); + elt->index = size_int (i); + elt->value = convert_tree (element_type, val, location); + + if (!TREE_CONSTANT (elt->value)) + is_constant = false; + } + + tree ret = build_constructor (type_tree, init); + if (is_constant) + TREE_CONSTANT (ret) = 1; + + return ret; + } + tree sink = NULL_TREE; bool is_constant = true; tree field = TYPE_FIELDS (type_tree); @@ -1951,7 +1989,7 @@ convert_tree (tree type_tree, tree expr_tree, location_t location) return fold_convert_loc (location, type_tree, expr_tree); else if (TREE_CODE (type_tree) == RECORD_TYPE || TREE_CODE (type_tree) == UNION_TYPE - || TREE_CODE (type_tree) == ARRAY_TYPE) + || TREE_CODE (type_tree) == ARRAY_TYPE || VECTOR_TYPE_P (type_tree)) { gcc_assert (int_size_in_bytes (type_tree) == int_size_in_bytes (TREE_TYPE (expr_tree))); diff --git a/gcc/testsuite/rust/compile/issue-4794.rs b/gcc/testsuite/rust/compile/issue-4794.rs new file mode 100644 index 000000000000..a42523a32fdc --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-4794.rs @@ -0,0 +1,35 @@ +#![feature(no_core, lang_items, repr_simd)] +#![no_core] + +#[lang = "sized"] +pub trait Sized {} + +#[repr(simd)] +pub struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +pub struct i32x4(pub i32, pub i32, pub i32, pub i32); + +pub fn make_u32x4(a: u32, b: u32, c: u32, d: u32) -> u32x4 { + u32x4(a, b, c, d) +} + +pub fn make_i32x4(a: i32, b: i32, c: i32, d: i32) -> i32x4 { + i32x4(a, b, c, d) +} + +pub fn pass_u32x4(v: u32x4) -> u32x4 { + v +} + +pub fn first_u32x4(v: u32x4) -> u32 { + v.0 +} + +pub fn third_i32x4(v: i32x4) -> i32 { + v.2 +} + +pub fn constructed_second_u32x4(a: u32, b: u32, c: u32, d: u32) -> u32 { + make_u32x4(a, b, c, d).1 +}
