[COMMITTED 43/43] gccrs: Support repr simd to setup a gcc vector type

arthur.cohen@opensrcsec.com arthur.cohen@opensrcsec.com
Thu Sep 10 08:19:56 GMT 2026


From: Philip Herron <herron.philip@googlemail.com>

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 <herron.philip@googlemail.com>
---
 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(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-4794.rs

diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index c3fb34260ee..1a815b9ffeb 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 00f35638144..ada66a2c7c6 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 00000000000..a42523a32fd
--- /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
+}
-- 
2.50.1



More information about the Gcc-rust mailing list