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) };
+}

Reply via email to