Skip to content

Commit 9cff3f5

Browse files
authored
[flang][OpenMP] Tolerate compiler directives in loop constructs (#169346)
PR168884 flagged compiler directives (!dir$ ...) inside OpenMP loop constructs as errors. This caused some customer applications to fail to compile (issue 169229). Downgrade the error to a warning, and gracefully ignore compiler directives when lowering loop constructs to MLIR. Fixes #169229
1 parent 4e7ce57 commit 9cff3f5

File tree

5 files changed

+49
-15
lines changed

5 files changed

+49
-15
lines changed

flang/lib/Lower/OpenMP/Utils.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,28 @@ static void processTileSizesFromOpenMPConstruct(
796796
}
797797
}
798798

799+
static pft::Evaluation *getNestedDoConstruct(pft::Evaluation &eval) {
800+
for (pft::Evaluation &nested : eval.getNestedEvaluations()) {
801+
// In an OpenMPConstruct there can be compiler directives:
802+
// 1 <<OpenMPConstruct>>
803+
// 2 CompilerDirective: !unroll
804+
// <<DoConstruct>> -> 8
805+
if (nested.getIf<parser::CompilerDirective>())
806+
continue;
807+
// Within a DoConstruct, there can be compiler directives, plus
808+
// there is a DoStmt before the body:
809+
// <<DoConstruct>> -> 8
810+
// 3 NonLabelDoStmt -> 7: do i = 1, n
811+
// <<DoConstruct>> -> 7
812+
if (nested.getIf<parser::NonLabelDoStmt>())
813+
continue;
814+
assert(nested.getIf<parser::DoConstruct>() &&
815+
"Unexpected construct in the nested evaluations");
816+
return &nested;
817+
}
818+
llvm_unreachable("Expected do loop to be in the nested evaluations");
819+
}
820+
799821
/// Populates the sizes vector with values if the given OpenMPConstruct
800822
/// contains a loop construct with an inner tiling construct.
801823
void collectTileSizesFromOpenMPConstruct(
@@ -818,7 +840,7 @@ int64_t collectLoopRelatedInfo(
818840
int64_t numCollapse = 1;
819841

820842
// Collect the loops to collapse.
821-
lower::pft::Evaluation *doConstructEval = &eval.getFirstNestedEvaluation();
843+
lower::pft::Evaluation *doConstructEval = getNestedDoConstruct(eval);
822844
if (doConstructEval->getIf<parser::DoConstruct>()->IsDoConcurrent()) {
823845
TODO(currentLocation, "Do Concurrent in Worksharing loop construct");
824846
}
@@ -844,7 +866,7 @@ void collectLoopRelatedInfo(
844866
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
845867

846868
// Collect the loops to collapse.
847-
lower::pft::Evaluation *doConstructEval = &eval.getFirstNestedEvaluation();
869+
lower::pft::Evaluation *doConstructEval = getNestedDoConstruct(eval);
848870
if (doConstructEval->getIf<parser::DoConstruct>()->IsDoConcurrent()) {
849871
TODO(currentLocation, "Do Concurrent in Worksharing loop construct");
850872
}
@@ -885,9 +907,8 @@ void collectLoopRelatedInfo(
885907
iv.push_back(bounds->name.thing.symbol);
886908
loopVarTypeSize = std::max(loopVarTypeSize,
887909
bounds->name.thing.symbol->GetUltimate().size());
888-
collapseValue--;
889-
doConstructEval =
890-
&*std::next(doConstructEval->getNestedEvaluations().begin());
910+
if (--collapseValue)
911+
doConstructEval = getNestedDoConstruct(*doConstructEval);
891912
} while (collapseValue > 0);
892913

893914
convertLoopBounds(converter, currentLocation, result, loopVarTypeSize);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ void OmpStructureChecker::CheckNestedBlock(const parser::OpenMPLoopConstruct &x,
267267
for (auto &stmt : body) {
268268
if (auto *dir{parser::Unwrap<parser::CompilerDirective>(stmt)}) {
269269
context_.Say(dir->source,
270-
"Compiler directives are not allowed inside OpenMP loop constructs"_err_en_US);
270+
"Compiler directives are not allowed inside OpenMP loop constructs"_warn_en_US);
271271
} else if (parser::Unwrap<parser::DoConstruct>(stmt)) {
272272
++nestedCount;
273273
} else if (auto *omp{parser::Unwrap<parser::OpenMPLoopConstruct>(stmt)}) {

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2419,13 +2419,6 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
24192419
}
24202420
}
24212421
CheckAssocLoopLevel(level, GetAssociatedClause());
2422-
} else {
2423-
unsigned version{context_.langOptions().OpenMPVersion};
2424-
context_.Say(GetContext().directiveSource,
2425-
"A DO loop must follow the %s directive"_err_en_US,
2426-
parser::ToUpperCaseLetters(
2427-
llvm::omp::getOpenMPDirectiveName(GetContext().directive, version)
2428-
.str()));
24292422
}
24302423
}
24312424
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 %s -o - | FileCheck %s
2+
3+
! Check that this compiles successfully, but not rely on any specific output.
4+
5+
!CHECK: omp.parallel
6+
7+
program omp_cdir_crash
8+
implicit none
9+
integer, parameter :: n = 10
10+
real :: a(n)
11+
integer :: i
12+
13+
!$omp parallel do
14+
!dir$ unroll
15+
do i = 1, n
16+
a(i) = real(i)
17+
end do
18+
!$omp end parallel do
19+
20+
print *, 'a(1)=', a(1), ' a(n)=', a(n)
21+
end program omp_cdir_crash

flang/test/Semantics/OpenMP/loop-association.f90

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@
3333
END DO outer
3434

3535
! Accept directives between parallel do and actual loop.
36-
!ERROR: A DO loop must follow the PARALLEL DO directive
3736
!$OMP PARALLEL DO
3837
!WARNING: Unrecognized compiler directive was ignored [-Wignored-directive]
39-
!ERROR: Compiler directives are not allowed inside OpenMP loop constructs
38+
!WARNING: Compiler directives are not allowed inside OpenMP loop constructs
4039
!DIR$ VECTOR ALIGNED
4140
DO 20 i=1,N
4241
a = a + 0.5

0 commit comments

Comments
 (0)