From: Yap Zhi Heng <[email protected]>
gcc/rust/ChangeLog:
* util/rust-intrinsic-values.h (Intrinsics): Add new entries for atomic
fence
function names.
* backend/rust-intrinsic-handlers.h (inner::atomic_fence): New function
for compiling
atomic fence intrinsics.
(atomic_fence): New function to handle atomic_fence and its variants.
* backend/rust-intrinsic-handlers.cc (inner:atomic_fence): Implement.
(atomic_fence): Implement.
* backend/rust-compile-intrinsic.cc (generic_intrinsics): Add entries
for the new atomic
fence intrinsics.
* typecheck/rust-hir-type-check-intrinsic.cc (intrinsic_rules):
Likewise, but for type
checking.
gcc/testsuite/ChangeLog:
* rust/execute/torture/atomic_load.rs: Add an atomic_fence.
* rust/execute/torture/atomic_store.rs: Likewise.
Signed-off-by: Yap Zhi Heng <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/3a53dbd73d9a77402ec7ba28466e219c1c091067
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4993
gcc/rust/backend/rust-compile-intrinsic.cc | 13 +++++++++
gcc/rust/backend/rust-intrinsic-handlers.cc | 29 +++++++++++++++++++
gcc/rust/backend/rust-intrinsic-handlers.h | 1 +
.../rust-hir-type-check-intrinsic.cc | 9 ++++++
gcc/rust/util/rust-intrinsic-values.h | 12 ++++++++
.../rust/execute/torture/atomic_load.rs | 3 ++
.../rust/execute/torture/atomic_store.rs | 3 ++
7 files changed, 70 insertions(+)
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 5ebcec660..994dda03c 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -180,6 +180,19 @@ static const std::map<std::string, Intrinsic::CompileFn>
intrinsics = {
{IValue::ATOMIC_UMIN_RELAXED,
handlers::atomic_minmax (handlers::AtomicMinMaxKind::UnsignedMin,
__ATOMIC_RELAXED)},
+ {IValue::ATOMIC_FENCE, handlers::atomic_fence (true, __ATOMIC_SEQ_CST)},
+ {IValue::ATOMIC_FENCE_ACQ, handlers::atomic_fence (true, __ATOMIC_ACQUIRE)},
+ {IValue::ATOMIC_FENCE_REL, handlers::atomic_fence (true, __ATOMIC_RELEASE)},
+ {IValue::ATOMIC_FENCE_ACQREL,
+ handlers::atomic_fence (true, __ATOMIC_ACQ_REL)},
+ {IValue::ATOMIC_SINGLETHREADFENCE,
+ handlers::atomic_fence (false, __ATOMIC_SEQ_CST)},
+ {IValue::ATOMIC_SINGLETHREADFENCE_ACQ,
+ handlers::atomic_fence (false, __ATOMIC_ACQUIRE)},
+ {IValue::ATOMIC_SINGLETHREADFENCE_REL,
+ handlers::atomic_fence (false, __ATOMIC_RELEASE)},
+ {IValue::ATOMIC_SINGLETHREADFENCE_ACQREL,
+ handlers::atomic_fence (false, __ATOMIC_ACQ_REL)},
{IValue::UNCHECKED_ADD, handlers::unchecked_op (PLUS_EXPR)},
{IValue::UNCHECKED_SUB, handlers::unchecked_op (MINUS_EXPR)},
{IValue::UNCHECKED_MUL, handlers::unchecked_op (MULT_EXPR)},
diff --git a/gcc/rust/backend/rust-intrinsic-handlers.cc
b/gcc/rust/backend/rust-intrinsic-handlers.cc
index 84eb4cbbb..dcaf046a4 100644
--- a/gcc/rust/backend/rust-intrinsic-handlers.cc
+++ b/gcc/rust/backend/rust-intrinsic-handlers.cc
@@ -794,6 +794,27 @@ atomic_minmax (IntrinsicCtx &ctx, AtomicMinMaxKind kind,
int ordering)
Backend::return_statement (ctx.fn, expected, UNDEF_LOCATION));
}
+static void
+atomic_fence (IntrinsicCtx &ctx, bool is_multithread, int ordering)
+{
+ // Most intrinsic functions are pure but not the atomic ones
+ TREE_READONLY (ctx.fn) = 0;
+ TREE_SIDE_EFFECTS (ctx.fn) = 1;
+
+ auto builtin_decl = BuiltinsContext::get ().lookup_simple_builtin (
+ is_multithread ? "__atomic_thread_fence" : "__atomic_signal_fence");
+ rust_assert (builtin_decl);
+
+ auto fence = build_fold_addr_expr_loc (UNDEF_LOCATION, *builtin_decl);
+ auto memorder = make_unsigned_long_tree (ordering);
+ auto fence_call
+ = Backend::call_expression (fence, {memorder}, nullptr, UNDEF_LOCATION);
+ TREE_READONLY (fence_call) = 0;
+ TREE_SIDE_EFFECTS (fence_call) = 1;
+
+ ctx.add_statement (fence_call);
+}
+
// Shared inner implementation for ctlz and ctlz_nonzero.
//
// nonzero=false → ctlz: ctlz(0) is well-defined in Rust and must return
@@ -1291,6 +1312,14 @@ atomic_minmax (AtomicMinMaxKind kind, int ordering)
};
}
+Intrinsic::CompileFn
+atomic_fence (bool is_multithread, int ordering)
+{
+ return [is_multithread, ordering] (IntrinsicCtx &ctx) {
+ return inner::atomic_fence (ctx, is_multithread, ordering);
+ };
+}
+
Intrinsic::CompileFn
unchecked_op (tree_code op)
{
diff --git a/gcc/rust/backend/rust-intrinsic-handlers.h
b/gcc/rust/backend/rust-intrinsic-handlers.h
index 685612b2f..8d5cb9f73 100644
--- a/gcc/rust/backend/rust-intrinsic-handlers.h
+++ b/gcc/rust/backend/rust-intrinsic-handlers.h
@@ -214,6 +214,7 @@ Intrinsic::CompileFn atomic_compare_exchange (bool weak,
int success_ordering,
int failure_ordering);
Intrinsic::CompileFn atomic_minmax (handlers::AtomicMinMaxKind kind,
int ordering);
+Intrinsic::CompileFn atomic_fence (bool is_multithread, int ordering);
Intrinsic::CompileFn unchecked_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 8a632fae8..c423cbb43 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc
@@ -359,6 +359,15 @@ const std::unordered_map<std::string, IntrinsicRules>
{1,
{IRT::MutPtrFirstGeneric, IRT::FirstGeneric, IRT::FirstGeneric},
IRT::TupleFirstGenericAndBool}},
+ // pub fn atomic_fence*/atomic_singlethreadfence*();
+ {IValue::ATOMIC_FENCE, {0, {}, IRT::Unit}},
+ {IValue::ATOMIC_FENCE_ACQ, {0, {}, IRT::Unit}},
+ {IValue::ATOMIC_FENCE_REL, {0, {}, IRT::Unit}},
+ {IValue::ATOMIC_FENCE_ACQREL, {0, {}, IRT::Unit}},
+ {IValue::ATOMIC_SINGLETHREADFENCE, {0, {}, IRT::Unit}},
+ {IValue::ATOMIC_SINGLETHREADFENCE_ACQ, {0, {}, IRT::Unit}},
+ {IValue::ATOMIC_SINGLETHREADFENCE_REL, {0, {}, IRT::Unit}},
+ {IValue::ATOMIC_SINGLETHREADFENCE_ACQREL, {0, {}, IRT::Unit}},
// pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;
{IValue::UNCHECKED_ADD,
{1, {IRT::FirstGeneric, IRT::FirstGeneric}, IRT::FirstGeneric}},
diff --git a/gcc/rust/util/rust-intrinsic-values.h
b/gcc/rust/util/rust-intrinsic-values.h
index 37f61f8cb..2560739b8 100644
--- a/gcc/rust/util/rust-intrinsic-values.h
+++ b/gcc/rust/util/rust-intrinsic-values.h
@@ -196,6 +196,18 @@ public:
static constexpr auto &ATOMIC_CXCHGWEAK_ACQREL_FAILRELAXED
= "atomic_cxchgweak_acqrel_failrelaxed";
+ static constexpr auto &ATOMIC_FENCE = "atomic_fence";
+ static constexpr auto &ATOMIC_FENCE_ACQ = "atomic_fence_acq";
+ static constexpr auto &ATOMIC_FENCE_REL = "atomic_fence_rel";
+ static constexpr auto &ATOMIC_FENCE_ACQREL = "atomic_fence_acqrel";
+ static constexpr auto &ATOMIC_SINGLETHREADFENCE = "atomic_singlethreadfence";
+ static constexpr auto &ATOMIC_SINGLETHREADFENCE_ACQ
+ = "atomic_singlethreadfence_acq";
+ static constexpr auto &ATOMIC_SINGLETHREADFENCE_REL
+ = "atomic_singlethreadfence_rel";
+ static constexpr auto &ATOMIC_SINGLETHREADFENCE_ACQREL
+ = "atomic_singlethreadfence_acqrel";
+
static constexpr auto &UNCHECKED_ADD = "unchecked_add";
static constexpr auto &UNCHECKED_SUB = "unchecked_sub";
static constexpr auto &UNCHECKED_MUL = "unchecked_mul";
diff --git a/gcc/testsuite/rust/execute/torture/atomic_load.rs
b/gcc/testsuite/rust/execute/torture/atomic_load.rs
index bddfff563..d967911fc 100644
--- a/gcc/testsuite/rust/execute/torture/atomic_load.rs
+++ b/gcc/testsuite/rust/execute/torture/atomic_load.rs
@@ -68,6 +68,7 @@ extern "rust-intrinsic" {
pub fn atomic_load_acquire<T: Copy>(src: *const T) -> T;
pub fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
pub fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
+ pub fn atomic_fence();
}
fn main() -> u32 {
@@ -88,6 +89,8 @@ fn main() -> u32 {
src = 4;
four = atomic_load_unordered(&src);
+
+ atomic_fence();
}
(four + three + two + one) - 10
diff --git a/gcc/testsuite/rust/execute/torture/atomic_store.rs
b/gcc/testsuite/rust/execute/torture/atomic_store.rs
index e6602a75b..cc6d3e5bf 100644
--- a/gcc/testsuite/rust/execute/torture/atomic_store.rs
+++ b/gcc/testsuite/rust/execute/torture/atomic_store.rs
@@ -68,6 +68,7 @@ extern "rust-intrinsic" {
pub fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
+ pub fn atomic_fence();
}
fn main() -> u32 {
@@ -89,6 +90,8 @@ fn main() -> u32 {
atomic_store_unordered(&mut dst, 4);
four = dst;
+
+ atomic_fence();
}
(four + three + two + one) - 10
--
2.56.0