[Flang][OpenMP] Add more sema checks for ordered construct

This patch fixes a bug to allow ordered construct within a non-worksharing loop, also adds more sema checks.

Reviewed By: kiranchandramohan

Differential Revision: https://reviews.llvm.org/D98733
This commit is contained in:
Arnamoy Bhattacharyya 2021-03-19 14:54:06 -04:00
parent 1066dcb550
commit e27654f737
3 changed files with 109 additions and 1 deletions

View File

@ -343,12 +343,22 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
void OmpStructureChecker::CheckIfDoOrderedClause(
const parser::OmpBlockDirective &blkDirective) {
if (blkDirective.v == llvm::omp::OMPD_ordered) {
if (!FindClauseParent(llvm::omp::Clause::OMPC_ordered)) {
// Loops
if (llvm::omp::doSet.test(GetContextParent().directive) &&
!FindClauseParent(llvm::omp::Clause::OMPC_ordered)) {
context_.Say(blkDirective.source,
"The ORDERED clause must be present on the loop"
" construct if any ORDERED region ever binds"
" to a loop region arising from the loop construct."_err_en_US);
}
// Other disallowed nestings, these directives do not support
// ordered clause in them, so no need to check
else if (llvm::omp::nestedOrderedErrSet.test(
GetContextParent().directive)) {
context_.Say(blkDirective.source,
"`ORDERED` region may not be closely nested inside of "
"`CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region."_err_en_US);
}
}
}

View File

@ -73,6 +73,9 @@ static OmpDirectiveSet simdSet{Directive::OMPD_distribute_parallel_do_simd,
Directive::OMPD_teams_distribute_simd};
static OmpDirectiveSet taskGeneratingSet{
OmpDirectiveSet{Directive::OMPD_task} | taskloopSet};
static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical,
Directive::OMPD_ordered, Directive::OMPD_atomic, Directive::OMPD_task,
Directive::OMPD_taskloop};
static OmpClauseSet privateSet{
Clause::OMPC_private, Clause::OMPC_firstprivate, Clause::OMPC_lastprivate};
static OmpClauseSet privateReductionSet{

View File

@ -0,0 +1,95 @@
! RUN: %S/test_errors.sh %s %t %flang -fopenmp
! OpenMP Version 4.5
! Various checks with the ordered construct
SUBROUTINE WORK(I)
INTEGER I
END SUBROUTINE WORK
SUBROUTINE ORDERED_GOOD(N)
INTEGER N, I, A(10), B(10), C(10)
!$OMP SIMD
DO I = 1,N
IF (I <= 10) THEN
!$OMP ORDERED SIMD
CALL WORK(I)
!$OMP END ORDERED
ENDIF
END DO
!$OMP END SIMD
END SUBROUTINE ORDERED_GOOD
SUBROUTINE ORDERED_BAD(N)
INTEGER N, I, A(10), B(10), C(10)
!$OMP DO SIMD
DO I = 1,N
IF (I <= 10) THEN
!ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct.
!$OMP ORDERED
CALL WORK(I)
!$OMP END ORDERED
ENDIF
END DO
!$OMP END DO SIMD
!$OMP PARALLEL DO
DO I = 1,N
IF (I <= 10) THEN
!ERROR: The ORDERED clause must be present on the loop construct if any ORDERED region ever binds to a loop region arising from the loop construct.
!$OMP ORDERED
CALL WORK(I)
!$OMP END ORDERED
ENDIF
END DO
!$OMP END PARALLEL DO
!$OMP CRITICAL
DO I = 1,N
IF (I <= 10) THEN
!ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
!$OMP ORDERED
CALL WORK(I)
!$OMP END ORDERED
ENDIF
END DO
!$OMP END CRITICAL
!$OMP CRITICAL
WRITE(*,*) I
!ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
!$OMP ORDERED
CALL WORK(I)
!$OMP END ORDERED
!$OMP END CRITICAL
!$OMP ORDERED
WRITE(*,*) I
IF (I <= 10) THEN
!ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
!$OMP ORDERED
CALL WORK(I)
!$OMP END ORDERED
ENDIF
!$OMP END ORDERED
!$OMP TASK
C = C - A * B
!ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
!$OMP ORDERED
CALL WORK(I)
!$OMP END ORDERED
!$OMP END TASK
!$OMP TASKLOOP
DO I = 1,N
IF (I <= 10) THEN
!ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
!$OMP ORDERED
CALL WORK(I)
!$OMP END ORDERED
ENDIF
END DO
!$OMP END TASKLOOP
END SUBROUTINE ORDERED_BAD