Skip to content

Commit de8f50c

Browse files
author
Ferran Toda
committed
looprange clause semantics
1 parent c761405 commit de8f50c

File tree

6 files changed

+105
-4
lines changed

6 files changed

+105
-4
lines changed

flang/lib/Lower/OpenMP/Clauses.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,7 @@ Link make(const parser::OmpClause::Link &inp,
10381038

10391039
LoopRange make(const parser::OmpClause::Looprange &inp,
10401040
semantics::SemanticsContext &semaCtx) {
1041-
llvm_unreachable("Unimplemented: looprange");
1041+
TODO_NOLOC("looprange clause");
10421042
}
10431043

10441044
Map make(const parser::OmpClause::Map &inp,

flang/lib/Semantics/check-omp-loop.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
305305
beginName.v == llvm::omp::Directive::OMPD_distribute_simd) {
306306
CheckDistLinear(x);
307307
}
308+
if (beginName.v == llvm::omp::Directive::OMPD_fuse) {
309+
CheckLooprangeBounds(x);
310+
}
308311
}
309312

310313
const parser::Name OmpStructureChecker::GetLoopIndex(
@@ -453,6 +456,32 @@ void OmpStructureChecker::CheckDistLinear(
453456
}
454457
}
455458

459+
void OmpStructureChecker::CheckLooprangeBounds(
460+
const parser::OpenMPLoopConstruct &x) {
461+
const parser::OmpClauseList &clauseList = x.BeginDir().Clauses();
462+
if (!clauseList.v.empty()) {
463+
for (auto &clause : clauseList.v) {
464+
if (const auto *lrClause{
465+
std::get_if<parser::OmpClause::Looprange>(&clause.u)}) {
466+
if (const auto first{GetIntValue(std::get<0>((lrClause->v).t))}) {
467+
if (const auto count{GetIntValue(std::get<1>((lrClause->v).t))}) {
468+
auto &loopConsList =
469+
std::get<std::list<parser::NestedConstruct>>(x.t);
470+
if (loopConsList.size() < (unsigned)(*first + *count - 1)) {
471+
context_.Say(clause.source,
472+
"The loop range indicated in the %s clause"
473+
" must not be out of the bounds of the Loop Sequence"
474+
" following the construct."_err_en_US,
475+
parser::ToUpperCaseLetters(clause.source.ToString()));
476+
}
477+
}
478+
}
479+
return;
480+
}
481+
}
482+
}
483+
}
484+
456485
void OmpStructureChecker::Leave(const parser::OpenMPLoopConstruct &x) {
457486
const parser::OmpClauseList &clauseList{x.BeginDir().Clauses()};
458487

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3107,9 +3107,11 @@ CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Safelen, OMPC_safelen)
31073107
CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Simdlen, OMPC_simdlen)
31083108

31093109
void OmpStructureChecker::Enter(const parser::OmpClause::Looprange &x) {
3110-
context_.Say(GetContext().clauseSource,
3111-
"LOOPRANGE clause is not implemented yet"_err_en_US,
3112-
ContextDirectiveAsFortran());
3110+
CheckAllowedClause(llvm::omp::Clause::OMPC_looprange);
3111+
auto &first = std::get<0>(x.v.t);
3112+
auto &count = std::get<1>(x.v.t);
3113+
RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_looprange, count);
3114+
RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_looprange, first);
31133115
}
31143116

31153117
// Restrictions specific to each clause are implemented apart from the

flang/lib/Semantics/check-omp-structure.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ class OmpStructureChecker
297297
void CheckAtomicWrite(const parser::OpenMPAtomicConstruct &x);
298298
void CheckAtomicUpdate(const parser::OpenMPAtomicConstruct &x);
299299

300+
void CheckLooprangeBounds(const parser::OpenMPLoopConstruct &x);
300301
void CheckDistLinear(const parser::OpenMPLoopConstruct &x);
301302
void CheckSIMDNest(const parser::OpenMPConstruct &x);
302303
void CheckTargetNest(const parser::OpenMPConstruct &x);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
! RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case %s
2+
! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
3+
4+
subroutine openmp_fuse(x)
5+
6+
integer, intent(inout)::x
7+
8+
!CHECK: !$omp fuse looprange
9+
!$omp fuse looprange(1,2)
10+
!CHECK: do
11+
do x = 1, 100
12+
call F1()
13+
!CHECK: end do
14+
end do
15+
!CHECK: do
16+
do x = 1, 100
17+
call F1()
18+
!CHECK: end do
19+
end do
20+
!CHECK: do
21+
do x = 1, 100
22+
call F1()
23+
!CHECK: end do
24+
end do
25+
!CHECK: !$omp end fuse
26+
!$omp end fuse
27+
28+
!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct
29+
!PARSE-TREE: OmpBeginLoopDirective
30+
!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = fuse
31+
!PARSE-TREE: OmpClauseList -> OmpClause -> Looprange -> OmpLoopRangeClause
32+
!PARSE-TREE: Scalar -> Integer -> Constant -> Expr = '1_4'
33+
!PARSE-TREE: LiteralConstant -> IntLiteralConstant = '1'
34+
!PARSE-TREE: Scalar -> Integer -> Constant -> Expr = '2_4'
35+
!PARSE-TREE: LiteralConstant -> IntLiteralConstant = '2'
36+
37+
END subroutine openmp_fuse
38+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
! Testing the Semantics of clauses on loop transformation directives
2+
3+
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
4+
5+
6+
subroutine loop_transformation_construct1
7+
implicit none
8+
integer, parameter:: i = 5
9+
integer :: x
10+
integer :: v(i)
11+
12+
!$omp fuse looprange(1,2)
13+
do x = 1, i
14+
v(x) = x * 2
15+
end do
16+
do x = 1, i
17+
v(x) = x * 2
18+
end do
19+
!$omp end fuse
20+
21+
!ERROR: The loop range indicated in the LOOPRANGE(5,2) clause must not be out of the bounds of the Loop Sequence following the construct.
22+
!$omp fuse looprange(5,2)
23+
do x = 1, i
24+
v(x) = x * 2
25+
end do
26+
do x = 1, i
27+
v(x) = x * 2
28+
end do
29+
!$omp end fuse
30+
end subroutine
31+

0 commit comments

Comments
 (0)