Skip to content

Commit 6f00949

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_TREE_U8): Define macro. (RUST_INT_TREE_U16): Likewise. (RUST_INT_TREE_U32): Likewise. (RUST_INT_TREE_U64): Likewise. (RUST_INT_TREE_U128): Likewise. (RUST_INT_TREE_I8): Likewise. (RUST_INT_TREE_I16): Likewise. (RUST_INT_TREE_I32): Likewise. (RUST_INT_TREE_I64): Likewise. (RUST_INT_TREE_I128): Likewise. (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 to set up rust_int_trees. (init): Call setup_normal_integers. * backend/rust-compile-type.cc (TyTyResolveCompile::visit): Use rust_int_trees via macros to obtain integer type trees. * config-lang.in (gtfiles): Add "rust-backend.h". 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 6f00949

File tree

6 files changed

+132
-27
lines changed

6 files changed

+132
-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, element_precision (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 = RUST_INT_TREE_I8;
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 = RUST_INT_TREE_I16;
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 = RUST_INT_TREE_I32;
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 = RUST_INT_TREE_I64;
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 = RUST_INT_TREE_I128;
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 = RUST_INT_TREE_U8;
545535
return;
546536

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

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

557545
case TyTy::UintType::U64:
558-
translated = Backend::named_type ("u64", Backend::integer_type (true, 64),
559-
BUILTINS_LOCATION);
546+
translated = RUST_INT_TREE_U64;
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 = RUST_INT_TREE_U128;
566551
return;
567552
}
568553
}

gcc/rust/config-lang.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ lang_dirs=libgrust
3535
gtfiles="\
3636
\$(srcdir)/rust/rust-lang.cc \$(srcdir)/rust/backend/rust-constexpr.cc \
3737
\$(srcdir)/rust/backend/rust-tree.h \$(srcdir)/rust/backend/rust-tree.cc \
38+
\$(srcdir)/rust/rust-backend.h \
3839
"

gcc/rust/rust-backend.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@
3939
// The backend representation of a variable.
4040
class Bvariable;
4141

42+
// rust integer trees
43+
44+
#define RUST_INT_TREE_U8 (rust_int_trees[0])
45+
#define RUST_INT_TREE_U16 (rust_int_trees[1])
46+
#define RUST_INT_TREE_U32 (rust_int_trees[2])
47+
#define RUST_INT_TREE_U64 (rust_int_trees[3])
48+
#define RUST_INT_TREE_U128 (rust_int_trees[4])
49+
50+
#define RUST_INT_TREE_I8 (rust_int_trees[5])
51+
#define RUST_INT_TREE_I16 (rust_int_trees[6])
52+
#define RUST_INT_TREE_I32 (rust_int_trees[7])
53+
#define RUST_INT_TREE_I64 (rust_int_trees[8])
54+
#define RUST_INT_TREE_I128 (rust_int_trees[9])
55+
56+
extern GTY (()) tree rust_int_trees[10];
57+
extern const char *rust_int_names[10];
58+
4259
// The backend interface. This is a pure abstract class that a
4360
// specific backend will implement.
4461

gcc/rust/rust-gcc.cc

Lines changed: 94 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"
@@ -83,6 +84,11 @@ Bvariable::error_variable ()
8384
return new Bvariable (error_mark_node);
8485
}
8586

87+
// (u, i) X (8, 16, 32, 64, 128)
88+
tree rust_int_trees[10];
89+
const char *rust_int_names[10]
90+
= {"u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128"};
91+
8692
// This file implements the interface between the Rust frontend proper
8793
// and the gcc IR. This implements specific instantiations of
8894
// abstract classes defined by the Rust frontend proper. The Rust
@@ -95,9 +101,97 @@ namespace Backend {
95101

96102
// Define the built-in functions that are exposed to GCCRust.
97103

104+
static void
105+
setup_normal_integers ()
106+
{
107+
// we should have QImode
108+
RUST_INT_TREE_U8 = make_unsigned_type (8);
109+
RUST_INT_TREE_I8 = 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+
int idx = exact_log2 (normal_int_sizes[i]) - 3;
123+
124+
// if the size wasn't a power of 2, idx == -4
125+
126+
if (idx < 0 || idx > 5)
127+
continue;
128+
129+
if (rust_int_trees[idx] != NULL_TREE)
130+
continue;
131+
132+
rust_int_trees[idx] = normal_int_trees[2 * i];
133+
rust_int_trees[5 + idx] = normal_int_trees[2 * i + 1];
134+
}
135+
136+
// look through int_n_data for more integer types
137+
for (size_t i = 0, j = 0; i < 5 && j < NUM_INT_N_ENTS;)
138+
{
139+
if (rust_int_trees[i] != NULL_TREE)
140+
{
141+
i++;
142+
continue;
143+
}
144+
145+
if (!int_n_enabled_p[j] || int_n_data[j].bitsize < (8u << i))
146+
{
147+
j++;
148+
}
149+
else if (int_n_data[j].bitsize > (8u << i))
150+
{
151+
i++;
152+
}
153+
else
154+
{
155+
rust_int_trees[i] = make_unsigned_type (8 << i);
156+
rust_int_trees[5 + i] = make_signed_type (8 << i);
157+
i++;
158+
j++;
159+
}
160+
}
161+
162+
// use _BitInt where we have to (and can)
163+
for (int i = 0; i < 5; i++)
164+
{
165+
if (rust_int_trees[i] == NULL_TREE)
166+
{
167+
bitint_info b_info;
168+
if (targetm.c.bitint_type_info (8 << i, &b_info))
169+
{
170+
rust_debug ("filling in integer size %u with _BitInt", 8u << i);
171+
rust_int_trees[i] = build_bitint_type (8 << i, true);
172+
rust_int_trees[5 + i] = build_bitint_type (8 << i, false);
173+
}
174+
}
175+
}
176+
177+
// TODO: bootleg _BitInt where necessary?
178+
179+
// not much can be done for now -- fill with error_mark_node
180+
for (size_t i = 0; i < 10; i++)
181+
if (rust_int_trees[i] == NULL_TREE)
182+
rust_int_trees[i] = error_mark_node;
183+
184+
// name types
185+
for (size_t i = 0; i < 10; i++)
186+
rust_int_trees[i]
187+
= named_type (rust_int_names[i], rust_int_trees[i], BUILTINS_LOCATION);
188+
}
189+
98190
void
99191
init ()
100192
{
193+
setup_normal_integers ();
194+
101195
/* We need to define the fetch_and_add functions, since we use them
102196
for ++ and --. */
103197
// 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)