From: Enes Cevik <[email protected]>
This patch implements the 'min_align_of' compiler intrinsic. It
resolves the minimum alignment of a given compile-time sized type
and returns it as a size_type_node integer constant expression.
gcc/rust/ChangeLog:
* backend/rust-compile-intrinsic.cc (generic_intrinsics): Add
min_align_of to map.
* backend/rust-intrinsic-handlers.cc (min_align_of_handler):
New function.
* backend/rust-intrinsic-handlers.h (min_align_of_handler):
New declaration.
gcc/testsuite/ChangeLog:
* rust/execute/min_align_of.rs: New test.
Signed-off-by: Enes Cevik <[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/6dae3d0f957eb21b9ed9d0a2472dcd851a156b38
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4582
gcc/rust/backend/rust-compile-intrinsic.cc | 1 +
gcc/rust/backend/rust-intrinsic-handlers.cc | 39 +++++++++++++++++++++
gcc/rust/backend/rust-intrinsic-handlers.h | 1 +
gcc/testsuite/rust/execute/min_align_of.rs | 29 +++++++++++++++
4 files changed, 70 insertions(+)
create mode 100644 gcc/testsuite/rust/execute/min_align_of.rs
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 1456f88df..ab6423092 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -30,6 +30,7 @@ using IValue = Values::Intrinsics;
static const std::map<std::string, handlers::HandlerBuilder> generic_intrinsics
= {{IValue::OFFSET, handlers::offset},
{IValue::SIZE_OF, handlers::sizeof_handler},
+ {IValue::MIN_ALIGN_OF, handlers::min_align_of_handler},
{IValue::TRANSMUTE, handlers::transmute},
{IValue::ROTATE_LEFT, handlers::rotate_left},
{IValue::ROTATE_RIGHT, handlers::rotate_right},
diff --git a/gcc/rust/backend/rust-intrinsic-handlers.cc
b/gcc/rust/backend/rust-intrinsic-handlers.cc
index dab2ca861..55bc06385 100644
--- a/gcc/rust/backend/rust-intrinsic-handlers.cc
+++ b/gcc/rust/backend/rust-intrinsic-handlers.cc
@@ -1612,6 +1612,45 @@ sizeof_handler (Context *ctx, TyTy::FnType *fntype)
return fndecl;
}
+/**
+ * pub fn min_align_of<T>() -> usize;
+ */
+tree
+min_align_of_handler (Context *ctx, TyTy::FnType *fntype)
+{
+ // min_align_of has _zero_ parameters its parameter is the generic one
+ rust_assert (fntype->get_params ().size () == 0);
+
+ tree lookup = NULL_TREE;
+ if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+ return lookup;
+
+ auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+ // get the template parameter type tree fn min_align_of<T>();
+ rust_assert (fntype->get_num_substitutions () == 1);
+ auto ¶m_mapping = fntype->get_substs ().at (0);
+ const auto param_tyty = param_mapping.get_param_ty ();
+ auto resolved_tyty = param_tyty->resolve ();
+ tree template_parameter_type
+ = TyTyResolveCompile::compile (ctx, resolved_tyty);
+
+ enter_intrinsic_block (ctx, fndecl);
+
+ // BUILTIN min_align_of FN BODY BEGIN
+ tree align_expr
+ = build_int_cst (size_type_node, TYPE_ALIGN_UNIT
(template_parameter_type));
+
+ auto return_statement
+ = Backend::return_statement (fndecl, align_expr, UNDEF_LOCATION);
+ ctx->add_statement (return_statement);
+ // BUILTIN min_align_of FN BODY END
+
+ finalize_intrinsic_block (ctx, fndecl);
+
+ return fndecl;
+}
+
tree
offset (Context *ctx, TyTy::FnType *fntype)
{
diff --git a/gcc/rust/backend/rust-intrinsic-handlers.h
b/gcc/rust/backend/rust-intrinsic-handlers.h
index f4c36b3fe..8a5605366 100644
--- a/gcc/rust/backend/rust-intrinsic-handlers.h
+++ b/gcc/rust/backend/rust-intrinsic-handlers.h
@@ -57,6 +57,7 @@ tree rotate_right (Context *ctx, TyTy::FnType *fntype);
const HandlerBuilder wrapping_op (tree_code op);
tree offset (Context *ctx, TyTy::FnType *fntype);
tree sizeof_handler (Context *ctx, TyTy::FnType *fntype);
+tree min_align_of_handler (Context *ctx, TyTy::FnType *fntype);
tree transmute (Context *ctx, TyTy::FnType *fntype);
tree rotate (Context *ctx, TyTy::FnType *fntype, tree_code op);
tree uninit (Context *ctx, TyTy::FnType *fntype);
diff --git a/gcc/testsuite/rust/execute/min_align_of.rs
b/gcc/testsuite/rust/execute/min_align_of.rs
new file mode 100644
index 000000000..a1aa2272d
--- /dev/null
+++ b/gcc/testsuite/rust/execute/min_align_of.rs
@@ -0,0 +1,29 @@
+// { dg-require-effective-target lp64 }
+#![no_core]
+#![feature(no_core, intrinsics, lang_items)]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+extern "rust-intrinsic" {
+ pub fn min_align_of<T>() -> usize;
+}
+
+fn main() -> i32 {
+ let align_u16 = get_u16_align() as i32;
+ let align_u32 = get_i32_align() as i32;
+
+ if align_u16 != 2 || align_u32 != 4 {
+ 1
+ } else {
+ 0
+ }
+}
+
+pub fn get_u16_align() -> usize {
+ unsafe { min_align_of::<u16>() }
+}
+
+pub fn get_i32_align() -> usize {
+ unsafe { min_align_of::<i32>() }
+}
base-commit: ea3adb2cf4d302991ce671588cbe770931d64e34
--
2.54.0