https://gcc.gnu.org/g:5bea182f3db92485bd6f00125043a9192d425ac9

commit r17-1901-g5bea182f3db92485bd6f00125043a9192d425ac9
Author: Enes Cevik <[email protected]>
Date:   Mon Jun 8 18:05:22 2026 +0300

    gccrs: intrinsic: Add min_align_of
    
    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]>

Diff:
---
 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(+)

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc 
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 1456f88df985..ab6423092735 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 dab2ca861c77..55bc0638519b 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 &param_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 f4c36b3fe62d..8a5605366b33 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 000000000000..a1aa2272dce4
--- /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>() }
+}

Reply via email to