Skip to content

Commit e6d4b55

Browse files
committed
Fix u128 rotate operation on 32 bit targets
This tweaks how we handle the right hand side of rotate intrinsics and tweaks how we handle integers so that we can fall back on _BitInt(128) on some targets. gcc/rust/ChangeLog: * backend/rust-compile-intrinsic.cc: Include "convert.h". (rotate_handler): Convert the second parameter into an unsigned int. * rust-backend.h (rust_int_trees): Declare extern variable. (rust_int_names): Likewise. * rust-gcc.cc: Include "target.h". (rust_int_trees): Define variable. (rust_int_names): Likewise. (setup_normal_integers): Define static function. (init): Call setup_normal_integers. * backend/rust-compile-type.cc (TyTyResolveCompile::visit): Use rust_int_trees to obtain integer type trees. gcc/testsuite/ChangeLog: * rust/execute/torture/sip-hasher.rs: Enable on 32 bit targets. Signed-off-by: Owen Avery <[email protected]>
1 parent 3a57c56 commit e6d4b55

File tree

5 files changed

+119
-27
lines changed

5 files changed

+119
-27
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "rust-gcc.h"
2929
#include "fold-const.h"
3030
#include "langhooks.h"
31+
#include "convert.h"
3132
#include "rust-constexpr.h"
3233

3334
// declaration taken from "stringpool.h"
@@ -557,8 +558,16 @@ rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op)
557558
// BUILTIN rotate FN BODY BEGIN
558559
tree x = Backend::var_expression (x_param, UNDEF_LOCATION);
559560
tree y = Backend::var_expression (y_param, UNDEF_LOCATION);
561+
562+
tree y_mask
563+
= build_int_cst (unsigned_type_node, TYPE_SIZE (TREE_TYPE (x)) - 1);
564+
565+
tree y_truncated
566+
= fold_build2_loc (BUILTINS_LOCATION, BIT_AND_EXPR, unsigned_type_node,
567+
convert_to_integer (unsigned_type_node, y), y_mask);
568+
560569
tree rotate_expr
561-
= fold_build2_loc (BUILTINS_LOCATION, op, TREE_TYPE (x), x, y);
570+
= fold_build2_loc (BUILTINS_LOCATION, op, TREE_TYPE (x), x, y_truncated);
562571
auto return_statement
563572
= Backend::return_statement (fndecl, rotate_expr, UNDEF_LOCATION);
564573
ctx->add_statement (return_statement);

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

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -504,32 +504,23 @@ TyTyResolveCompile::visit (const TyTy::IntType &type)
504504
switch (type.get_int_kind ())
505505
{
506506
case TyTy::IntType::I8:
507-
translated = Backend::named_type ("i8", Backend::integer_type (false, 8),
508-
BUILTINS_LOCATION);
507+
translated = Backend::rust_int_trees[5];
509508
return;
510509

511510
case TyTy::IntType::I16:
512-
translated
513-
= Backend::named_type ("i16", Backend::integer_type (false, 16),
514-
BUILTINS_LOCATION);
511+
translated = Backend::rust_int_trees[6];
515512
return;
516513

517514
case TyTy::IntType::I32:
518-
translated
519-
= Backend::named_type ("i32", Backend::integer_type (false, 32),
520-
BUILTINS_LOCATION);
515+
translated = Backend::rust_int_trees[7];
521516
return;
522517

523518
case TyTy::IntType::I64:
524-
translated
525-
= Backend::named_type ("i64", Backend::integer_type (false, 64),
526-
BUILTINS_LOCATION);
519+
translated = Backend::rust_int_trees[8];
527520
return;
528521

529522
case TyTy::IntType::I128:
530-
translated
531-
= Backend::named_type ("i128", Backend::integer_type (false, 128),
532-
BUILTINS_LOCATION);
523+
translated = Backend::rust_int_trees[9];
533524
return;
534525
}
535526
}
@@ -540,29 +531,23 @@ TyTyResolveCompile::visit (const TyTy::UintType &type)
540531
switch (type.get_uint_kind ())
541532
{
542533
case TyTy::UintType::U8:
543-
translated = Backend::named_type ("u8", Backend::integer_type (true, 8),
544-
BUILTINS_LOCATION);
534+
translated = Backend::rust_int_trees[0];
545535
return;
546536

547537
case TyTy::UintType::U16:
548-
translated = Backend::named_type ("u16", Backend::integer_type (true, 16),
549-
BUILTINS_LOCATION);
538+
translated = Backend::rust_int_trees[1];
550539
return;
551540

552541
case TyTy::UintType::U32:
553-
translated = Backend::named_type ("u32", Backend::integer_type (true, 32),
554-
BUILTINS_LOCATION);
542+
translated = Backend::rust_int_trees[2];
555543
return;
556544

557545
case TyTy::UintType::U64:
558-
translated = Backend::named_type ("u64", Backend::integer_type (true, 64),
559-
BUILTINS_LOCATION);
546+
translated = Backend::rust_int_trees[3];
560547
return;
561548

562549
case TyTy::UintType::U128:
563-
translated
564-
= Backend::named_type ("u128", Backend::integer_type (true, 128),
565-
BUILTINS_LOCATION);
550+
translated = Backend::rust_int_trees[4];
566551
return;
567552
}
568553
}

gcc/rust/rust-backend.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ using Rust::GGC::Ident;
5050

5151
} // namespace GGC
5252

53+
extern tree rust_int_trees[10];
54+
extern const char *rust_int_names[10];
55+
5356
void init ();
5457

5558
// Name/type/location. Used for function parameters, struct fields,

gcc/rust/rust-gcc.cc

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "builtins.h"
4646
#include "print-tree.h"
4747
#include "attribs.h"
48+
#include "target.h"
4849

4950
#include "rust-location.h"
5051
#include "rust-linemap.h"
@@ -95,9 +96,104 @@ namespace Backend {
9596

9697
// Define the built-in functions that are exposed to GCCRust.
9798

99+
// (u, i) X (8, 16, 32, 64, 128)
100+
tree rust_int_trees[10];
101+
const char *rust_int_names[10]
102+
= {"u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128"};
103+
104+
static void
105+
setup_normal_integers ()
106+
{
107+
// we should have QImode
108+
rust_int_trees[0] = make_unsigned_type (8);
109+
rust_int_trees[5] = make_signed_type (8);
110+
111+
// look through integer types intended for C
112+
const int normal_int_sizes[4]
113+
= {INT_TYPE_SIZE, SHORT_TYPE_SIZE, LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE};
114+
const tree normal_int_trees[8]
115+
= {unsigned_type_node, integer_type_node,
116+
short_unsigned_type_node, short_integer_type_node,
117+
long_unsigned_type_node, long_integer_type_node,
118+
long_long_unsigned_type_node, long_long_integer_type_node};
119+
120+
for (size_t i = 0; i < 4; i++)
121+
{
122+
// check for a power of 2 or 0
123+
if (normal_int_sizes[i] & (normal_int_sizes[i] - 1))
124+
continue;
125+
126+
// assume size is not 0
127+
int idx = __builtin_ctz (normal_int_sizes[i]) - 3;
128+
if (idx < 0 || idx > 5)
129+
continue;
130+
131+
if (rust_int_trees[idx] != NULL_TREE)
132+
continue;
133+
134+
rust_int_trees[idx] = normal_int_trees[2 * i];
135+
rust_int_trees[5 + idx] = normal_int_trees[2 * i + 1];
136+
}
137+
138+
// look through int_n_data for more integer types
139+
for (size_t i = 0, j = 0; i < 5 && j < NUM_INT_N_ENTS;)
140+
{
141+
if (rust_int_trees[i] != NULL_TREE)
142+
{
143+
i++;
144+
continue;
145+
}
146+
147+
if (!int_n_enabled_p[j] || int_n_data[j].bitsize < (8u << i))
148+
{
149+
j++;
150+
}
151+
else if (int_n_data[j].bitsize > (8u << i))
152+
{
153+
i++;
154+
}
155+
else
156+
{
157+
rust_int_trees[i] = make_unsigned_type (8 << i);
158+
rust_int_trees[5 + i] = make_signed_type (8 << i);
159+
i++;
160+
j++;
161+
}
162+
}
163+
164+
// use _BitInt where we have to (and can)
165+
for (int i = 0; i < 5; i++)
166+
{
167+
if (rust_int_trees[i] == NULL_TREE)
168+
{
169+
bitint_info b_info;
170+
if (targetm.c.bitint_type_info (8 << i, &b_info))
171+
{
172+
rust_debug ("filling in integer size %u with _BitInt", 8u << i);
173+
rust_int_trees[i] = build_bitint_type (8 << i, true);
174+
rust_int_trees[5 + i] = build_bitint_type (8 << i, false);
175+
}
176+
}
177+
}
178+
179+
// TODO: bootleg _BitInt where necessary?
180+
181+
// not much can be done for now -- fill with error_mark_node
182+
for (size_t i = 0; i < 10; i++)
183+
if (rust_int_trees[i] == NULL_TREE)
184+
rust_int_trees[i] = error_mark_node;
185+
186+
// name types
187+
for (size_t i = 0; i < 10; i++)
188+
rust_int_trees[i]
189+
= named_type (rust_int_names[i], rust_int_trees[i], BUILTINS_LOCATION);
190+
}
191+
98192
void
99193
init ()
100194
{
195+
setup_normal_integers ();
196+
101197
/* We need to define the fetch_and_add functions, since we use them
102198
for ++ and --. */
103199
// tree t = this->integer_type (true, BITS_PER_UNIT)->get_tree ();

gcc/testsuite/rust/execute/torture/sip-hasher.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// { dg-skip-if "" { *-*-* } { "-m32" } { "" } }
21
// { dg-options "-w" }
32
// { dg-output "Hash: 0x63d53fd2170bbb8c\r*\n" }
43
#![feature(intrinsics)]

0 commit comments

Comments
 (0)