[llvm] 3590a91 - [flang][OpenMP] Frontend support for DEVICE_SAFESYNC (#163560)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 20 06:12:00 PDT 2025
Author: Krzysztof Parzyszek
Date: 2025-10-20T08:11:55-05:00
New Revision: 3590a912daba875e0f2019039b8372501f13453c
URL: https://github.com/llvm/llvm-project/commit/3590a912daba875e0f2019039b8372501f13453c
DIFF: https://github.com/llvm/llvm-project/commit/3590a912daba875e0f2019039b8372501f13453c.diff
LOG: [flang][OpenMP] Frontend support for DEVICE_SAFESYNC (#163560)
Add parsing and semantic checks for DEVICE_SAFESYNC clause. No lowering.
Added:
Modified:
flang/include/flang/Lower/OpenMP/Clauses.h
flang/include/flang/Parser/dump-parse-tree.h
flang/include/flang/Parser/parse-tree.h
flang/lib/Lower/OpenMP/Clauses.cpp
flang/lib/Parser/openmp-parsers.cpp
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/resolve-directives.cpp
flang/test/Parser/OpenMP/requires.f90
llvm/include/llvm/Frontend/OpenMP/ClauseT.h
llvm/include/llvm/Frontend/OpenMP/OMP.td
Removed:
################################################################################
diff --git a/flang/include/flang/Lower/OpenMP/Clauses.h b/flang/include/flang/Lower/OpenMP/Clauses.h
index 273e61166fd9d..74924661d9a03 100644
--- a/flang/include/flang/Lower/OpenMP/Clauses.h
+++ b/flang/include/flang/Lower/OpenMP/Clauses.h
@@ -214,6 +214,7 @@ using Depend = tomp::clause::DependT<TypeTy, IdTy, ExprTy>;
using Destroy = tomp::clause::DestroyT<TypeTy, IdTy, ExprTy>;
using Detach = tomp::clause::DetachT<TypeTy, IdTy, ExprTy>;
using Device = tomp::clause::DeviceT<TypeTy, IdTy, ExprTy>;
+using DeviceSafesync = tomp::clause::DeviceSafesyncT<TypeTy, IdTy, ExprTy>;
using DeviceType = tomp::clause::DeviceTypeT<TypeTy, IdTy, ExprTy>;
using DistSchedule = tomp::clause::DistScheduleT<TypeTy, IdTy, ExprTy>;
using Doacross = tomp::clause::DoacrossT<TypeTy, IdTy, ExprTy>;
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 35017909d9091..5677277a9b381 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -559,6 +559,7 @@ class ParseTreeDumper {
NODE(OmpDeviceClause, Modifier)
NODE(parser, OmpDeviceModifier)
NODE_ENUM(OmpDeviceModifier, Value)
+ NODE(parser, OmpDeviceSafesyncClause)
NODE(parser, OmpDeviceTypeClause)
NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
NODE(parser, OmpDirectiveName)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index bb3af9e75df3e..6dd4f2492cf22 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4418,6 +4418,14 @@ struct OmpDeviceClause {
std::tuple<MODIFIERS(), ScalarIntExpr> t;
};
+// Ref: [6.0:356-362]
+//
+// device-safesync-clause ->
+// DEVICE_SAFESYNC [(scalar-logical-const-expr)] // since 6.0
+struct OmpDeviceSafesyncClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpDeviceSafesyncClause, ScalarLogicalConstantExpr);
+};
+
// Ref: [5.0:180-185], [5.1:210-216], [5.2:275]
//
// device-type-clause ->
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index ba34212dddba9..2a4ebf10bcafd 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -740,6 +740,18 @@ Device make(const parser::OmpClause::Device &inp,
/*DeviceDescription=*/makeExpr(t1, semaCtx)}};
}
+DeviceSafesync make(const parser::OmpClause::DeviceSafesync &inp,
+ semantics::SemanticsContext &semaCtx) {
+ // inp.v -> std::optional<parser::OmpDeviceSafesyncClause>
+ auto &&maybeRequired = maybeApply(
+ [&](const parser::OmpDeviceSafesyncClause &c) {
+ return makeExpr(c.v, semaCtx);
+ },
+ inp.v);
+
+ return DeviceSafesync{/*Required=*/std::move(maybeRequired)};
+}
+
DeviceType make(const parser::OmpClause::DeviceType &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpDeviceTypeClause
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index d677e14530215..56fcac3e741a9 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1159,6 +1159,9 @@ TYPE_PARSER( //
construct<OmpDestroyClause>(Parser<OmpObject>{}))))) ||
"DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
parenthesized(Parser<OmpDeviceClause>{}))) ||
+ "DEVICE_SAFESYNC" >>
+ construct<OmpClause>(construct<OmpClause::DeviceSafesync>(
+ maybe(parenthesized(scalarLogicalConstantExpr)))) ||
"DEVICE_TYPE" >> construct<OmpClause>(construct<OmpClause::DeviceType>(
parenthesized(Parser<OmpDeviceTypeClause>{}))) ||
"DIST_SCHEDULE" >>
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index ea6fe43f07de8..e015e948bc701 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1535,6 +1535,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
[&](auto &&s) {
using TypeS = llvm::remove_cvref_t<decltype(s)>;
if constexpr ( //
+ std::is_same_v<TypeS, parser::OmpClause::DeviceSafesync> ||
std::is_same_v<TypeS, parser::OmpClause::DynamicAllocators> ||
std::is_same_v<TypeS, parser::OmpClause::ReverseOffload> ||
std::is_same_v<TypeS, parser::OmpClause::SelfMaps> ||
@@ -5194,6 +5195,10 @@ void OmpStructureChecker::Enter(
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_atomic_default_mem_order);
}
+void OmpStructureChecker::Enter(const parser::OmpClause::DeviceSafesync &x) {
+ CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_device_safesync);
+}
+
void OmpStructureChecker::Enter(const parser::OmpClause::DynamicAllocators &x) {
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_dynamic_allocators);
}
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 7067ed3d99286..db061bdce18ea 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -586,6 +586,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
[&](auto &&s) {
using TypeS = llvm::remove_cvref_t<decltype(s)>;
if constexpr ( //
+ std::is_same_v<TypeS, OmpClause::DeviceSafesync> ||
std::is_same_v<TypeS, OmpClause::DynamicAllocators> ||
std::is_same_v<TypeS, OmpClause::ReverseOffload> ||
std::is_same_v<TypeS, OmpClause::SelfMaps> ||
diff --git a/flang/test/Parser/OpenMP/requires.f90 b/flang/test/Parser/OpenMP/requires.f90
index 8169403835705..ab4f4371480f7 100644
--- a/flang/test/Parser/OpenMP/requires.f90
+++ b/flang/test/Parser/OpenMP/requires.f90
@@ -1,5 +1,5 @@
-!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=50 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
-!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=50 %s | FileCheck --check-prefix="PARSE-TREE" %s
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
!$omp requires atomic_default_mem_order(seq_cst)
@@ -44,4 +44,13 @@
!PARSE-TREE: | | | bool = 'false'
!PARSE-TREE: | Flags = None
+!$omp requires device_safesync
+
+!UNPARSE: !$OMP REQUIRES DEVICE_SAFESYNC
+
+!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPRequiresConstruct -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = requires
+!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceSafesync
+!PARSE-TREE: | Flags = None
+
end
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index 1a01fa66c5379..87b95200b2459 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -541,6 +541,14 @@ struct DeviceT {
std::tuple<OPT(DeviceModifier), DeviceDescription> t;
};
+// [6.0:362]
+template <typename T, typename I, typename E> //
+struct DeviceSafesyncT {
+ using Requires = E;
+ using WrapperTrait = std::true_type;
+ OPT(Requires) v;
+};
+
// V5.2: [13.1] `device_type` clause
template <typename T, typename I, typename E> //
struct DeviceTypeT {
@@ -1332,14 +1340,15 @@ using WrapperClausesT = std::variant<
AtomicDefaultMemOrderT<T, I, E>, AtT<T, I, E>, BindT<T, I, E>,
CollapseT<T, I, E>, ContainsT<T, I, E>, CopyinT<T, I, E>,
CopyprivateT<T, I, E>, DefaultT<T, I, E>, DestroyT<T, I, E>,
- DetachT<T, I, E>, DeviceTypeT<T, I, E>, DynamicAllocatorsT<T, I, E>,
- EnterT<T, I, E>, ExclusiveT<T, I, E>, FailT<T, I, E>, FilterT<T, I, E>,
- FinalT<T, I, E>, FirstprivateT<T, I, E>, HasDeviceAddrT<T, I, E>,
- HintT<T, I, E>, HoldsT<T, I, E>, InclusiveT<T, I, E>, IndirectT<T, I, E>,
- InitializerT<T, I, E>, IsDevicePtrT<T, I, E>, LinkT<T, I, E>,
- MessageT<T, I, E>, NocontextT<T, I, E>, NontemporalT<T, I, E>,
- NovariantsT<T, I, E>, NumTeamsT<T, I, E>, NumThreadsT<T, I, E>,
- OrderedT<T, I, E>, PartialT<T, I, E>, PriorityT<T, I, E>, PrivateT<T, I, E>,
+ DetachT<T, I, E>, DeviceSafesyncT<T, I, E>, DeviceTypeT<T, I, E>,
+ DynamicAllocatorsT<T, I, E>, EnterT<T, I, E>, ExclusiveT<T, I, E>,
+ FailT<T, I, E>, FilterT<T, I, E>, FinalT<T, I, E>, FirstprivateT<T, I, E>,
+ HasDeviceAddrT<T, I, E>, HintT<T, I, E>, HoldsT<T, I, E>,
+ InclusiveT<T, I, E>, IndirectT<T, I, E>, InitializerT<T, I, E>,
+ IsDevicePtrT<T, I, E>, LinkT<T, I, E>, MessageT<T, I, E>,
+ NocontextT<T, I, E>, NontemporalT<T, I, E>, NovariantsT<T, I, E>,
+ NumTeamsT<T, I, E>, NumThreadsT<T, I, E>, OrderedT<T, I, E>,
+ PartialT<T, I, E>, PriorityT<T, I, E>, PrivateT<T, I, E>,
ProcBindT<T, I, E>, ReverseOffloadT<T, I, E>, SafelenT<T, I, E>,
SelfMapsT<T, I, E>, SeverityT<T, I, E>, SharedT<T, I, E>, SimdlenT<T, I, E>,
SizesT<T, I, E>, PermutationT<T, I, E>, ThreadLimitT<T, I, E>,
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index edcf7a92c2a84..61a1a05f6e904 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -163,6 +163,10 @@ def OMPC_Device : Clause<[Spelling<"device">]> {
let clangClass = "OMPDeviceClause";
let flangClass = "OmpDeviceClause";
}
+def OMPC_DeviceSafesync : Clause<[Spelling<"device_safesync">]> {
+ let flangClass = "OmpDeviceSafesyncClause";
+ let isValueOptional = true;
+}
def OMPC_DeviceType : Clause<[Spelling<"device_type">]> {
let flangClass = "OmpDeviceTypeClause";
}
@@ -1018,6 +1022,7 @@ def OMP_Requires : Directive<[Spelling<"requires">]> {
let allowedOnceClauses = [
VersionedClause<OMPC_UnifiedAddress>,
VersionedClause<OMPC_UnifiedSharedMemory>,
+ VersionedClause<OMPC_DeviceSafesync, 60>,
// OpenMP 5.2 Spec: If an implementation is not supporting a requirement
// (reverse offload in this case) then it should give compile-time error
// termination.
More information about the llvm-commits
mailing list