Skip to content

Commit af4b290

Browse files
committed
gccrs: Support repr simd to setup a gcc vector type
GCC makes this stuff really straight forward which is nice. Fixes #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>
1 parent a263235 commit af4b290

3 files changed

Lines changed: 81 additions & 2 deletions

File tree

gcc/rust/backend/rust-compile-type.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,14 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
334334
}
335335
}
336336
}
337+
else if (repr.repr_kind == TyTy::ADTType::ReprKind::SIMD)
338+
{
339+
TyTy::VariantDef &variant = *type.get_variants ().at (0);
340+
auto element = variant.get_fields ().at (0)->get_field_type ();
341+
auto inner_type = compile (ctx, element);
337342

338-
// compilation of non-transparent ADTs below
343+
type_record = build_vector_type (inner_type, variant.num_fields ());
344+
}
339345
else if (!type.is_enum ())
340346
{
341347
rust_assert (type.number_of_variants () == 1);

gcc/rust/rust-gcc.cc

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,18 @@ struct_field_expression (tree struct_tree, size_t index, location_t location)
888888
{
889889
if (error_operand_p (struct_tree))
890890
return error_mark_node;
891+
892+
if (VECTOR_TYPE_P (TREE_TYPE (struct_tree)))
893+
{
894+
tree vec_type = TREE_TYPE (struct_tree);
895+
tree element_type = TREE_TYPE (vec_type);
896+
tree part_width = TYPE_SIZE (element_type);
897+
tree bit_offset = bitsize_int (index * tree_to_uhwi (part_width));
898+
899+
return fold_build3_loc (location, BIT_FIELD_REF, element_type,
900+
struct_tree, part_width, bit_offset);
901+
}
902+
891903
gcc_assert (TREE_CODE (TREE_TYPE (struct_tree)) == RECORD_TYPE
892904
|| TREE_CODE (TREE_TYPE (struct_tree)) == UNION_TYPE);
893905
tree field = TYPE_FIELDS (TREE_TYPE (struct_tree));
@@ -1277,6 +1289,32 @@ constructor_expression (tree type_tree, bool is_variant,
12771289
vec<constructor_elt, va_gc> *init;
12781290
vec_alloc (init, union_index != -1 ? 1 : vals.size ());
12791291

1292+
if (VECTOR_TYPE_P (type_tree))
1293+
{
1294+
tree element_type = TREE_TYPE (type_tree);
1295+
bool is_constant = true;
1296+
for (size_t i = 0; i < vals.size (); ++i)
1297+
{
1298+
tree val = vals[i];
1299+
if (error_operand_p (val))
1300+
return error_mark_node;
1301+
1302+
constructor_elt empty = {NULL, NULL};
1303+
constructor_elt *elt = init->quick_push (empty);
1304+
elt->index = size_int (i);
1305+
elt->value = convert_tree (element_type, val, location);
1306+
1307+
if (!TREE_CONSTANT (elt->value))
1308+
is_constant = false;
1309+
}
1310+
1311+
tree ret = build_constructor (type_tree, init);
1312+
if (is_constant)
1313+
TREE_CONSTANT (ret) = 1;
1314+
1315+
return ret;
1316+
}
1317+
12801318
tree sink = NULL_TREE;
12811319
bool is_constant = true;
12821320
tree field = TYPE_FIELDS (type_tree);
@@ -1951,7 +1989,7 @@ convert_tree (tree type_tree, tree expr_tree, location_t location)
19511989
return fold_convert_loc (location, type_tree, expr_tree);
19521990
else if (TREE_CODE (type_tree) == RECORD_TYPE
19531991
|| TREE_CODE (type_tree) == UNION_TYPE
1954-
|| TREE_CODE (type_tree) == ARRAY_TYPE)
1992+
|| TREE_CODE (type_tree) == ARRAY_TYPE || VECTOR_TYPE_P (type_tree))
19551993
{
19561994
gcc_assert (int_size_in_bytes (type_tree)
19571995
== int_size_in_bytes (TREE_TYPE (expr_tree)));
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![feature(no_core, lang_items, repr_simd)]
2+
#![no_core]
3+
4+
#[lang = "sized"]
5+
pub trait Sized {}
6+
7+
#[repr(simd)]
8+
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
9+
10+
#[repr(simd)]
11+
pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
12+
13+
pub fn make_u32x4(a: u32, b: u32, c: u32, d: u32) -> u32x4 {
14+
u32x4(a, b, c, d)
15+
}
16+
17+
pub fn make_i32x4(a: i32, b: i32, c: i32, d: i32) -> i32x4 {
18+
i32x4(a, b, c, d)
19+
}
20+
21+
pub fn pass_u32x4(v: u32x4) -> u32x4 {
22+
v
23+
}
24+
25+
pub fn first_u32x4(v: u32x4) -> u32 {
26+
v.0
27+
}
28+
29+
pub fn third_i32x4(v: i32x4) -> i32 {
30+
v.2
31+
}
32+
33+
pub fn constructed_second_u32x4(a: u32, b: u32, c: u32, d: u32) -> u32 {
34+
make_u32x4(a, b, c, d).1
35+
}

0 commit comments

Comments
 (0)