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