diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-10-27 16:30:02 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-27 16:30:02 +0000 |
commit | 2d1c287af3a074d40e84234be9feca904af627d5 (patch) | |
tree | 4e48388aef6905dddc47ff3cc33832d657fcaa40 /gcc | |
parent | 353ed6ce8add32b84f0fdfbcbc020d8f7154530d (diff) | |
parent | fc2aa3cd381613a69129cd183a352f3e3c23643b (diff) | |
download | gcc-2d1c287af3a074d40e84234be9feca904af627d5.zip gcc-2d1c287af3a074d40e84234be9feca904af627d5.tar.gz gcc-2d1c287af3a074d40e84234be9feca904af627d5.tar.bz2 |
Merge #1620
1620: Intrinsics unchecked ops r=CohenArthur a=CohenArthur
Addresses #658
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-intrinsic.cc | 80 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/intrinsics-6.rs | 21 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/intrinsics-7.rs | 10 |
3 files changed, 111 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 8c6fbd7..142a217 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -34,6 +34,22 @@ namespace Rust { namespace Compile { +static bool +is_basic_integer_type (TyTy::BaseType *type) +{ + switch (type->get_kind ()) + { + case TyTy::INT: + case TyTy::UINT: + case TyTy::USIZE: + case TyTy::ISIZE: + return true; + default: + return false; + break; + } +} + static tree offset_handler (Context *ctx, TyTy::FnType *fntype); static tree @@ -98,6 +114,17 @@ atomic_store_handler (int ordering) } static inline tree +unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op); + +const static std::function<tree (Context *, TyTy::FnType *)> +unchecked_op_handler (tree_code op) +{ + return [op] (Context *ctx, TyTy::FnType *fntype) { + return unchecked_op_inner (ctx, fntype, op); + }; +} + +static inline tree sorry_handler (Context *ctx, TyTy::FnType *fntype) { rust_sorry_at (fntype->get_locus (), "intrinsic %qs is not yet implemented", @@ -125,6 +152,13 @@ static const std::map<std::string, {"atomic_store_release", atomic_store_handler (__ATOMIC_RELEASE)}, {"atomic_store_relaxed", atomic_store_handler (__ATOMIC_RELAXED)}, {"atomic_store_unordered", atomic_store_handler (__ATOMIC_RELAXED)}, + {"unchecked_add", unchecked_op_handler (PLUS_EXPR)}, + {"unchecked_sub", unchecked_op_handler (MINUS_EXPR)}, + {"unchecked_mul", unchecked_op_handler (MULT_EXPR)}, + {"unchecked_div", unchecked_op_handler (TRUNC_DIV_EXPR)}, + {"unchecked_rem", unchecked_op_handler (TRUNC_MOD_EXPR)}, + {"unchecked_shl", unchecked_op_handler (LSHIFT_EXPR)}, + {"unchecked_shr", unchecked_op_handler (RSHIFT_EXPR)}, }; Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {} @@ -714,6 +748,52 @@ atomic_store_handler_inner (Context *ctx, TyTy::FnType *fntype, int ordering) TREE_SIDE_EFFECTS (store_call) = 1; ctx->add_statement (store_call); + finalize_intrinsic_block (ctx, fndecl); + + return fndecl; +} + +static inline tree +unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op) +{ + rust_assert (fntype->get_params ().size () == 2); + rust_assert (fntype->get_num_substitutions () == 1); + + tree lookup = NULL_TREE; + if (check_for_cached_intrinsic (ctx, fntype, &lookup)) + return lookup; + + auto fndecl = compile_intrinsic_function (ctx, fntype); + + // setup the params + std::vector<Bvariable *> param_vars; + compile_fn_params (ctx, fntype, fndecl, ¶m_vars); + + if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars)) + return error_mark_node; + + enter_intrinsic_block (ctx, fndecl); + + // BUILTIN unchecked_<op> BODY BEGIN + + auto x = ctx->get_backend ()->var_expression (param_vars[0], Location ()); + auto y = ctx->get_backend ()->var_expression (param_vars[1], Location ()); + + auto *monomorphized_type + = fntype->get_substs ().at (0).get_param_ty ()->resolve (); + if (!is_basic_integer_type (monomorphized_type)) + rust_error_at (fntype->get_locus (), + "unchecked operation intrinsics can only be used with " + "basic integer types (got %qs)", + monomorphized_type->get_name ().c_str ()); + + auto expr = build2 (op, TREE_TYPE (x), x, y); + auto return_statement + = ctx->get_backend ()->return_statement (fndecl, {expr}, Location ()); + + ctx->add_statement (return_statement); + + // BUILTIN unchecked_<op> BODY END finalize_intrinsic_block (ctx, fndecl); diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-6.rs b/gcc/testsuite/rust/compile/torture/intrinsics-6.rs new file mode 100644 index 0000000..143b62a --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/intrinsics-6.rs @@ -0,0 +1,21 @@ +extern "rust-intrinsic" { + pub fn unchecked_add<T>(x: T, y: T) -> T; + pub fn unchecked_sub<T>(x: T, y: T) -> T; + pub fn unchecked_mul<T>(x: T, y: T) -> T; + pub fn unchecked_div<T>(x: T, y: T) -> T; + pub fn unchecked_rem<T>(x: T, y: T) -> T; + pub fn unchecked_shl<T>(x: T, y: T) -> T; + pub fn unchecked_shr<T>(x: T, y: T) -> T; +} + +fn main() -> i32 { + let zero0 = unsafe { (1 + 5) - unchecked_add(1, 5) }; + let zero1 = unsafe { (1 - 5) - unchecked_sub(1, 5) }; + let zero2 = unsafe { (1 * 5) - unchecked_mul(1, 5) }; + let zero3 = unsafe { (1 / 5) - unchecked_div(1, 5) }; + let zero4 = unsafe { (1 % 5) - unchecked_rem(1, 5) }; + let zero5 = unsafe { (1 << 5) - unchecked_shl(1, 5) }; + let zero6 = unsafe { (1 >> 5) - unchecked_shr(1, 5) }; + + zero0 + zero1 + zero2 + zero3 + zero4 + zero5 + zero6 +} diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-7.rs b/gcc/testsuite/rust/compile/torture/intrinsics-7.rs new file mode 100644 index 0000000..8e8c5fe --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/intrinsics-7.rs @@ -0,0 +1,10 @@ +extern "rust-intrinsic" { + pub fn unchecked_add<T>(x: T, y: T) -> T; + // { dg-error "unchecked operation intrinsics can only be used with basic integer types .got .NotAdd.." "" { target *-*-* } .-1 } +} + +fn main() { + struct NotAdd; + + unsafe { unchecked_add(NotAdd, NotAdd) }; +} |