diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -175,6 +175,14 @@ llvm::StringRef getClauseName(llvm::omp::Clause clause) override; llvm::StringRef getDirectiveName(llvm::omp::Directive directive) override; + + std::optional chunkSize{0}; + std::optional GetChunkSize() { return chunkSize; } + void SetChunkSize(const parser::ScalarIntExpr &chunkExpr) { + if (std::optional v{GetIntValue(chunkExpr)}) { + chunkSize.emplace(*v); + } + } }; } // namespace Fortran::semantics #endif // FORTRAN_SEMANTICS_CHECK_OMP_STRUCTURE_H_ diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -582,6 +582,19 @@ std::get>(x.t)}) { RequiresPositiveParameter( llvm::omp::Clause::OMPC_schedule, *chunkExpr, "chunk size"); + + if (kind == parser::OmpScheduleClause::ScheduleType::Static) { + if (const auto cv{GetIntValue(chunkExpr)}) { + const auto cs{GetChunkSize()}; + if (!*cs) { + SetChunkSize(*chunkExpr); + } else if (cs != cv) { + context_.Say(GetContext().clauseSource, + "The value of chunk size in SCHEDULE clause must" + " be the same for all threads."_err_en_US); + } + } + } } } diff --git a/flang/test/Semantics/omp-schedule-teams01.f90 b/flang/test/Semantics/omp-schedule-teams01.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-schedule-teams01.f90 @@ -0,0 +1,26 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Thread Chunk Size - Schedule Clause + +program omp_doschedule + integer,parameter :: N = 14 + integer :: i + integer :: sumx + real :: B(N), C(N) + + !$omp parallel + !$omp do schedule(static, 4) + do i = 1,N + sumx = sumx + B(i) * C(i) + end do + + !ERROR: The value of chunk size in SCHEDULE clause must be the same for all threads. + !$omp do schedule(static, 8) + do i = 1,N + sumx = sumx + B(i) * C(i) + end do + + !$omp end do + !$omp end parallel + +end program omp_doschedule diff --git a/flang/test/Semantics/omp-schedule-teams02.f90 b/flang/test/Semantics/omp-schedule-teams02.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-schedule-teams02.f90 @@ -0,0 +1,41 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! OpenMP Version 4.5 +! 2.7.1 Thread Chunk Size - Schedule Clause , a positive case + +program omp_doschedule + + !DEF: /omp_doschedule/n PARAMETER ObjectEntity INTEGER(4) + integer, parameter :: n = 14 + !DEF: /omp_doschedule/i ObjectEntity INTEGER(4) + integer i + !DEF: /omp_doschedule/sumx ObjectEntity INTEGER(4) + integer sumx + !DEF: /omp_doschedule/b ObjectEntity REAL(4) + !REF: /omp_doschedule/n + !DEF: /omp_doschedule/c ObjectEntity REAL(4) + real b(n), c(n) + !$omp parallel + !$omp do schedule(static,4) + !DEF: /omp_doschedule/Block1/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + !REF: /omp_doschedule/n + do i=1,n + !REF: /omp_doschedule/sumx + !REF: /omp_doschedule/b + !REF: /omp_doschedule/Block1/Block1/i + !REF: /omp_doschedule/c + sumx = sumx+b(i)*c(i) + end do + !$omp do schedule(static,4) + !DEF: /omp_doschedule/Block1/Block2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) + !REF: /omp_doschedule/n + do i=1,n + !REF: /omp_doschedule/sumx + !REF: /omp_doschedule/b + !REF: /omp_doschedule/Block1/Block2/i + !REF: /omp_doschedule/c + sumx = sumx+b(i)*c(i) + end do + !$omp end do + !$omp end parallel + +end program omp_doschedule