[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
This commit is contained in:
sameeran joshi 2020-12-14 13:30:26 +05:30 committed by Sameeran joshi
parent 63ec9e40d1
commit f1569b1ece
9 changed files with 143 additions and 6 deletions

View file

@ -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;
};

View file

@ -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>(

View file

@ -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

View file

@ -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();

View file

@ -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();
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -446,7 +446,7 @@ def OMP_TaskGroup : Directive<"taskgroup"> {
];
}
def OMP_Flush : Directive<"flush"> {
let allowedClauses = [
let allowedOnceClauses = [
VersionedClause<OMPC_AcqRel, 50>,
VersionedClause<OMPC_Acquire, 50>,
VersionedClause<OMPC_Release, 50>,