summaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorsameeran joshi <sameeranjayant.joshi@amd.com>2020-12-14 13:30:26 +0530
committerSameeran joshi <joshisameeran17@gmail.com>2020-12-14 13:30:48 +0530
commitf1569b1ece5516d31d8c748f7b2981a688e32826 (patch)
treec8a4e5a22b3aaec857b438c92c40f4fdb5fe30a2 /flang
parent63ec9e40d10056b0f85605d585e7db0b4146851e (diff)
downloadllvm-f1569b1ece5516d31d8c748f7b2981a688e32826.tar.gz
[Flang][OpenMP-5.0] Semantic checks for flush construct.
From OMP 5.0 [2.17.8] Restriction: If memory-order-clause is release,acquire, or acq_rel, list items must not be specified on the flush directive. Reviewed By: kiranchandramohan, clementval Differential Revision: https://reviews.llvm.org/D89879
Diffstat (limited to 'flang')
-rw-r--r--flang/include/flang/Parser/parse-tree.h2
-rw-r--r--flang/lib/Lower/OpenMP.cpp3
-rw-r--r--flang/lib/Parser/openmp-parsers.cpp2
-rw-r--r--flang/lib/Parser/unparse.cpp2
-rw-r--r--flang/lib/Semantics/check-omp-structure.cpp12
-rw-r--r--flang/test/Semantics/omp-clause-validity01.f901
-rw-r--r--flang/test/Semantics/omp-flush01.f9039
-rw-r--r--flang/test/Semantics/omp-flush02.f9086
8 files changed, 142 insertions, 5 deletions
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 5d2909a4142a..27998c308cc0 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3747,7 +3747,7 @@ struct OpenMPCancelConstruct {
struct OpenMPFlushConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct);
CharBlock source;
- std::tuple<Verbatim, std::optional<OmpMemoryOrderClause>,
+ std::tuple<Verbatim, std::optional<std::list<OmpMemoryOrderClause>>,
std::optional<OmpObjectList>>
t;
};
diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index cfe4b0b86b67..97946caa68a0 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -109,7 +109,8 @@ genOMP(Fortran::lower::AbstractConverter &converter,
std::get<std::optional<Fortran::parser::OmpObjectList>>(
flushConstruct.t))
genObjectList(*ompObjectList, converter, operandRange);
- if (std::get<std::optional<Fortran::parser::OmpMemoryOrderClause>>(
+ if (std::get<std::optional<
+ std::list<Fortran::parser::OmpMemoryOrderClause>>>(
flushConstruct.t))
TODO("Handle OmpMemoryOrderClause");
converter.getFirOpBuilder().create<mlir::omp::FlushOp>(
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index fd209abc4138..67c377e798ca 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -331,7 +331,7 @@ TYPE_PARSER(sourced(construct<OmpAtomicClauseList>(
many(maybe(","_tok) >> sourced(Parser<OmpAtomicClause>{})))))
TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(verbatim("FLUSH"_tok),
- maybe(Parser<OmpMemoryOrderClause>{}),
+ many(maybe(","_tok) >> sourced(Parser<OmpMemoryOrderClause>{})),
maybe(parenthesized(Parser<OmpObjectList>{})))))
// Simple Standalone Directives
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index c5df6990d102..bd1c1a2c71eb 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2460,7 +2460,7 @@ public:
void Unparse(const OpenMPFlushConstruct &x) {
BeginOpenMP();
Word("!$OMP FLUSH ");
- Walk(std::get<std::optional<OmpMemoryOrderClause>>(x.t));
+ Walk(std::get<std::optional<std::list<OmpMemoryOrderClause>>>(x.t));
Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")");
Put("\n");
EndOpenMP();
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index e58e2e509fb8..978e1c7962a4 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -226,7 +226,17 @@ void OmpStructureChecker::Enter(const parser::OpenMPFlushConstruct &x) {
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_flush);
}
-void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &) {
+void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &x) {
+ if (FindClause(llvm::omp::Clause::OMPC_acquire) ||
+ FindClause(llvm::omp::Clause::OMPC_release) ||
+ FindClause(llvm::omp::Clause::OMPC_acq_rel)) {
+ if (const auto &flushList{
+ std::get<std::optional<parser::OmpObjectList>>(x.t)}) {
+ context_.Say(parser::FindSourceLocation(flushList),
+ "If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items "
+ "must not be specified on the FLUSH directive"_err_en_US);
+ }
+ }
dirContext_.pop_back();
}
diff --git a/flang/test/Semantics/omp-clause-validity01.f90 b/flang/test/Semantics/omp-clause-validity01.f90
index 601e39021e44..3f5345137866 100644
--- a/flang/test/Semantics/omp-clause-validity01.f90
+++ b/flang/test/Semantics/omp-clause-validity01.f90
@@ -487,6 +487,7 @@ use omp_lib
!$omp flush acq_rel
!$omp flush release
!$omp flush acquire
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
!$omp flush release (c)
!ERROR: SEQ_CST clause is not allowed on the FLUSH directive
!$omp flush seq_cst
diff --git a/flang/test/Semantics/omp-flush01.f90 b/flang/test/Semantics/omp-flush01.f90
new file mode 100644
index 000000000000..cca78e7a09cd
--- /dev/null
+++ b/flang/test/Semantics/omp-flush01.f90
@@ -0,0 +1,39 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+
+! 2.17.8 Flush construct [OpenMP 5.0]
+! memory-order-clause ->
+! acq_rel
+! release
+! acquire
+use omp_lib
+ implicit none
+
+ integer :: i, a, b
+ real, DIMENSION(10) :: array
+
+ a = 1.0
+ !$omp parallel num_threads(4)
+ !Only memory-order-clauses.
+ if (omp_get_thread_num() == 1) then
+ ! Allowed clauses.
+ !$omp flush acq_rel
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !$omp flush release
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !$omp flush acquire
+
+ !ERROR: expected end of line
+ !ERROR: expected end of line
+ !$omp flush private(array)
+ !ERROR: expected end of line
+ !ERROR: expected end of line
+ !$omp flush num_threads(4)
+
+ ! Mix allowed and not allowed clauses.
+ !ERROR: expected end of line
+ !ERROR: expected end of line
+ !$omp flush num_threads(4) acquire
+ end if
+ !$omp end parallel
+end
+
diff --git a/flang/test/Semantics/omp-flush02.f90 b/flang/test/Semantics/omp-flush02.f90
new file mode 100644
index 000000000000..6e417c49a3b0
--- /dev/null
+++ b/flang/test/Semantics/omp-flush02.f90
@@ -0,0 +1,86 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+
+! Check OpenMP 5.0 - 2.17.8 flush Construct
+! Restriction -
+! If memory-order-clause is release, acquire, or acq_rel, list items must not be specified on the flush directive.
+
+use omp_lib
+ implicit none
+
+ TYPE someStruct
+ REAL :: rr
+ end TYPE
+ integer :: i, a, b
+ real, DIMENSION(10) :: array
+ TYPE(someStruct) :: structObj
+
+ a = 1.0
+ !$omp parallel num_threads(4)
+ !No list flushes all.
+ if (omp_get_thread_num() == 1) THEN
+ !$omp flush
+ END IF
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !Only memory-order-clauses.
+ if (omp_get_thread_num() == 1) THEN
+ ! Not allowed clauses.
+ !ERROR: SEQ_CST clause is not allowed on the FLUSH directive
+ !$omp flush seq_cst
+ !ERROR: RELAXED clause is not allowed on the FLUSH directive
+ !$omp flush relaxed
+
+ ! Not allowed more than once.
+ !ERROR: At most one ACQ_REL clause can appear on the FLUSH directive
+ !$omp flush acq_rel acq_rel
+ !ERROR: At most one RELEASE clause can appear on the FLUSH directive
+ !$omp flush release release
+ !ERROR: At most one ACQUIRE clause can appear on the FLUSH directive
+ !$omp flush acquire acquire
+
+ ! Mix of allowed and not allowed.
+ !ERROR: SEQ_CST clause is not allowed on the FLUSH directive
+ !$omp flush seq_cst acquire
+ END IF
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ ! No memory-order-clause only list-items.
+ if (omp_get_thread_num() == 2) THEN
+ !$omp flush (a)
+ !$omp flush (i, a, b)
+ !$omp flush (array, structObj%rr)
+ ! Too many flush with repeating list items.
+ !$omp flush (i, a, b, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, b, b, b, b)
+ !ERROR: No explicit type declared for 'notpresentitem'
+ !$omp flush (notPresentItem)
+ END IF
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ if (omp_get_thread_num() == 3) THEN
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush acq_rel (array)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush acq_rel (array, a, i)
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush release (array)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush release (array, a)
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush acquire (array)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush acquire (array, a, structObj%rr)
+ END IF
+ !$omp end parallel
+
+ !$omp parallel num_threads(4)
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !$omp master
+ !$omp flush (array)
+ !$omp end master
+ !$omp end parallel
+end
+