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 ¶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 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>() } +}
