From: Arthur Cohen <[email protected]>
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.
Tested on x86_64-pc-linux-gnu.
---
gcc/rust/backend/rust-compile-intrinsic.cc | 1 +
gcc/rust/backend/rust-intrinsic-handlers.cc | 17 ++++++++++++++
gcc/rust/backend/rust-intrinsic-handlers.h | 2 ++
.../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(+)
create mode 100644 gcc/testsuite/rust/compile/exact_div.rs
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 89fb3d90250..312d0f77894 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 30521bca579..d9b56b7e341 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 9aa5e2aa339..8bccd65b071 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 1498a09c4da..ae1bc3e1dcf 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 0da1f0c3ac3..42af67988a5 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 00000000000..9e777a38431
--- /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) };
+}
--
2.55.0