https://gcc.gnu.org/g:0097a638f08ca72cd6fb9af762d4719244bbac83
commit r17-5710-g0097a638f08ca72cd6fb9af762d4719244bbac83 Author: Arthur Cohen <[email protected]> Date: Fri Oct 9 19:04:32 2026 +0200 gccrs: intrinsics: Add exact_div gcc/rust/ChangeLog: * util/rust-intrinsic-values.h: Declare the new intrinsic. * backend/rust-intrinsic-handlers.cc (exact_div_handler): Implement the new handler. * backend/rust-intrinsic-handlers.h (exact_div_handler): Declare it. * backend/rust-compile-intrinsic.cc: Use the new handler. * typecheck/rust-hir-type-check-intrinsic.cc: Give type information for exact_div. gcc/testsuite/ChangeLog: * rust/compile/exact_div.rs: New test. Diff: --- gcc/rust/backend/rust-compile-intrinsic.cc | 1 + gcc/rust/backend/rust-intrinsic-handlers.cc | 17 +++++++++++++++++ gcc/rust/backend/rust-intrinsic-handlers.h | 2 ++ .../typecheck/rust-hir-type-check-intrinsic.cc | 3 +++ gcc/rust/util/rust-intrinsic-values.h | 2 ++ gcc/testsuite/rust/compile/exact_div.rs | 22 ++++++++++++++++++++++ 6 files changed, 47 insertions(+) diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 89fb3d902501..312d0f778949 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -91,6 +91,7 @@ static const std::map<std::string, Intrinsic::CompileFn> intrinsics = { {IValue::FREM_FAST, handlers::fop_fast (ArithmeticOrLogicalOperator::MODULUS)}, {IValue::FLOAT_TO_INT_UNCHECKED, handlers::float_to_int_unchecked}, + {IValue::EXACT_DIV, handlers::exact_div_handler}, }; Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {} diff --git a/gcc/rust/backend/rust-intrinsic-handlers.cc b/gcc/rust/backend/rust-intrinsic-handlers.cc index 30521bca5793..d9b56b7e341e 100644 --- a/gcc/rust/backend/rust-intrinsic-handlers.cc +++ b/gcc/rust/backend/rust-intrinsic-handlers.cc @@ -1734,6 +1734,23 @@ assert_zero_valid_handler (IntrinsicCtx &ctx) ctx.add_statement (return_statement); } +void +exact_div_handler (IntrinsicCtx &ctx) +{ + auto lhs_param = ctx.param_vars.at (0); + auto rhs_param = ctx.param_vars.at (1); + + auto lhs = Backend::var_expression (lhs_param, ctx.loc); + auto rhs = Backend::var_expression (rhs_param, ctx.loc); + + auto div_expr + = build2_loc (ctx.loc, EXACT_DIV_EXPR, TREE_TYPE (lhs), lhs, rhs); + + auto return_stmt = Backend::return_statement (ctx.fn, div_expr, ctx.loc); + + ctx.add_statement (return_stmt); +} + void float_to_int_unchecked (IntrinsicCtx &ctx) { diff --git a/gcc/rust/backend/rust-intrinsic-handlers.h b/gcc/rust/backend/rust-intrinsic-handlers.h index 9aa5e2aa339d..8bccd65b0716 100644 --- a/gcc/rust/backend/rust-intrinsic-handlers.h +++ b/gcc/rust/backend/rust-intrinsic-handlers.h @@ -175,6 +175,8 @@ void write_bytes_handler (IntrinsicCtx &ctx); void arith_offset_handler (IntrinsicCtx &ctx); void assert_zero_valid_handler (IntrinsicCtx &ctx); +void exact_div_handler (IntrinsicCtx &ctx); + Intrinsic::CompileFn op_with_overflow (tree_code op); Intrinsic::CompileFn wrapping_op (tree_code op); diff --git a/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc b/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc index 1498a09c4da9..ae1bc3e1dcff 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc @@ -332,6 +332,9 @@ const std::unordered_map<std::string, IntrinsicRules> {IValue::FLOAT_TO_INT_UNCHECKED, {2, {IRT::FirstGeneric}, IRT::SecondGeneric}}, + // fn exact_div<T>(lhs: T, rhs: T) -> T + {IValue::EXACT_DIV, + {1, {IRT::FirstGeneric, IRT::FirstGeneric}, IRT::FirstGeneric}}, }; IntrinsicCheckResult diff --git a/gcc/rust/util/rust-intrinsic-values.h b/gcc/rust/util/rust-intrinsic-values.h index 0da1f0c3ac31..42af67988a52 100644 --- a/gcc/rust/util/rust-intrinsic-values.h +++ b/gcc/rust/util/rust-intrinsic-values.h @@ -183,6 +183,8 @@ public: static constexpr auto &FREM_FAST = "frem_fast"; static constexpr auto &FLOAT_TO_INT_UNCHECKED = "float_to_int_unchecked"; + + static constexpr auto &EXACT_DIV = "exact_div"; }; } // namespace Values } // namespace Rust diff --git a/gcc/testsuite/rust/compile/exact_div.rs b/gcc/testsuite/rust/compile/exact_div.rs new file mode 100644 index 000000000000..9e777a38431b --- /dev/null +++ b/gcc/testsuite/rust/compile/exact_div.rs @@ -0,0 +1,22 @@ +// { dg-additional-options "-fdump-tree-gimple" } + +#![feature(no_core)] +#![feature(intrinsics)] +#![feature(lang_items)] +#![no_core] + +// Scan for the exact division gimple operator +// { dg-final { scan-tree-dump-times "x /.ex. y" 1 gimple } } + +#[lang = "sized"] +trait Sized {} + +extern "rust-intrinsic" { + fn exact_div<T>(x: T, y: T) -> T; +} + +fn main() { + let b = 15; + + let _ = unsafe { exact_div(b, 5) }; +}
