[gccrs COMMIT] gccrs: Support repr simd to setup a gcc vector type

[email protected]
Newsgroups gmane.comp.gcc.rust,gmane.comp.gcc.patches
Message-ID <[email protected]>
From: Philip Herron <[email protected]>

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]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: https://github.com/Rust-GCC/gccrs/commit/af4b290158f953c4a2c338207bfa78728204e49b

The commit has been mentioned in the following issue(s):
 - Rust-GCC/gccrs#4794: https://github.com/Rust-GCC/gccrs/issues/4794

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4795

 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 c3fb34260..1a815b9ff 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 00f356381..ada66a2c7 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 000000000..a42523a32
--- /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
+}

base-commit: a263235e4f9da943366e08ebc4ecb799c50738bd
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.