[flang-commits] [flang] [flang][OpenMP] Provide reasons for calculated depths (PR #187781)
Krzysztof Parzyszek via flang-commits
flang-commits at lists.llvm.org
Fri Mar 20 12:56:15 PDT 2026
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/187781
If the depth (either semantic or perfect) was limited by some factor, include the reason for what caused the reduction.
Issue: https://github.com/llvm/llvm-project/issues/185287
>From ecee1cba7222a79a51a88c52d79240f4d65f4228 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Tue, 17 Mar 2026 13:08:46 -0500
Subject: [PATCH] [flang][OpenMP] Provide reasons for calculated depths
If the depth (either semantic or perfect) was limited by some factor,
include the reason for what caused the reduction.
Issue: https://github.com/llvm/llvm-project/issues/185287
---
flang/include/flang/Semantics/openmp-utils.h | 4 +-
flang/lib/Semantics/check-omp-loop.cpp | 12 ++-
flang/lib/Semantics/openmp-utils.cpp | 99 +++++++++++++------
flang/test/Semantics/OpenMP/do-collapse.f90 | 1 +
.../OpenMP/do-concurrent-collapse.f90 | 2 +
flang/test/Semantics/OpenMP/do08.f90 | 24 +++--
flang/test/Semantics/OpenMP/do13.f90 | 9 +-
flang/test/Semantics/OpenMP/do15.f90 | 3 +
flang/test/Semantics/OpenMP/do16.f90 | 2 +
flang/test/Semantics/OpenMP/do22.f90 | 2 +
flang/test/Semantics/OpenMP/tile07.f90 | 2 +
flang/test/Semantics/OpenMP/tile09.f90 | 63 ++++++++++++
12 files changed, 174 insertions(+), 49 deletions(-)
create mode 100644 flang/test/Semantics/OpenMP/tile09.f90
diff --git a/flang/include/flang/Semantics/openmp-utils.h b/flang/include/flang/Semantics/openmp-utils.h
index 555ab0cd2842a..de5f9cc9072a3 100644
--- a/flang/include/flang/Semantics/openmp-utils.h
+++ b/flang/include/flang/Semantics/openmp-utils.h
@@ -191,10 +191,10 @@ struct LoopSequence {
struct Depth {
// If this sequence is a nest, the depth of the Canonical Loop Nest rooted
// at this sequence. Otherwise unspecified.
- std::optional<int64_t> semantic;
+ WithReason<int64_t> semantic;
// If this sequence is a nest, the depth of the perfect Canonical Loop Nest
// rooted at this sequence. Otherwise unspecified.
- std::optional<int64_t> perfect;
+ WithReason<int64_t> perfect;
};
bool isNest() const { return length_ && *length_ == 1; }
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index 70d7040472a89..36b7b22de67ea 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -327,23 +327,25 @@ void OmpStructureChecker::CheckNestedConstruct(
auto &[haveSema, havePerf]{sequence.depth()};
if (dir != llvm::omp::Directive::OMPD_fuse) {
- auto &haveDepth = needPerfect ? havePerf : haveSema;
+ auto haveDepth = needPerfect ? havePerf : haveSema;
// If the present depth is 0, it's likely that the construct doesn't
// have any loops in it, which would be diagnosed above.
- if (needDepth && haveDepth > 0) {
- if (*needDepth.value > *haveDepth) {
+ if (needDepth && haveDepth.value > 0) {
+ if (*needDepth.value > *haveDepth.value) {
if (needPerfect) {
auto &msg{context_.Say(beginSource,
"This construct requires a perfect nest of depth %" PRId64
", but the associated nest is a perfect nest of depth %" PRId64
""_err_en_US,
- *needDepth.value, *haveDepth)};
+ *needDepth.value, *haveDepth.value)};
+ haveDepth.reason.AttachTo(msg);
needDepth.reason.AttachTo(msg);
} else {
auto &msg{context_.Say(beginSource,
"This construct requires a nest of depth %" PRId64
", but the associated nest has a depth of %" PRId64 ""_err_en_US,
- *needDepth.value, *haveDepth)};
+ *needDepth.value, *haveDepth.value)};
+ haveDepth.reason.AttachTo(msg);
needDepth.reason.AttachTo(msg);
}
}
diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index 96a117b9055ec..185673444f0f0 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -1157,20 +1157,6 @@ std::optional<int64_t> LoopSequence::getNestedLength() const {
}
LoopSequence::Depth LoopSequence::calculateDepths() const {
- auto plus{[](std::optional<int64_t> a,
- std::optional<int64_t> b) -> std::optional<int64_t> {
- if (a && b) {
- return *a + *b;
- }
- return std::nullopt;
- }};
-
- // The sequence length is calculated first, so we already know if this
- // sequence is a nest or not.
- if (!isNest()) {
- return Depth{0, 0};
- }
-
// Get the length of the nested sequence. The invalidIC_ and opaqueIC_
// members do not count canonical loop nests, but there can only be one
// for depth to make sense.
@@ -1178,24 +1164,61 @@ LoopSequence::Depth LoopSequence::calculateDepths() const {
// Get the depths of the code nested in this sequence (e.g. contained in
// entry_), and use it as the basis for the depths of entry_->owner.
auto [semaDepth, perfDepth]{getNestedDepths()};
- if (invalidIC_ || length.value_or(0) != 1) {
- semaDepth = perfDepth = 0;
- } else if (opaqueIC_ || length.value_or(0) != 1) {
- perfDepth = 0;
+ if (invalidIC_) {
+ parser::CharBlock source{*parser::GetSource(*invalidIC_)};
+ if (semaDepth.value > 9) {
+ semaDepth.value = 0;
+ semaDepth.reason.Say(
+ source, "This is not a valid intervening code"_because_en_US);
+ }
+ if (perfDepth.value > 0) {
+ perfDepth.value = 0;
+ perfDepth.reason.Say(
+ source, "This is not a valid intervening code"_because_en_US);
+ }
+ } else if (opaqueIC_) {
+ parser::CharBlock source{*parser::GetSource(*opaqueIC_)};
+ if (perfDepth.value > 0) {
+ perfDepth.value = 0;
+ perfDepth.reason.Say(
+ source, "This code prevents perfect nesting"_because_en_US);
+ }
+ }
+ if (length.value_or(0) != 1) {
+ // This may simply be the bottom of the loop nest. Only emit messages
+ // if the depths are reset back to 0.
+ if (entry_->owner) {
+ parser::CharBlock source{*parser::GetSource(*entry_->owner)};
+ if (semaDepth.value > 0) {
+ semaDepth.reason.Say(source,
+ "This construct does not contain a loop nest"_because_en_US);
+ }
+ if (perfDepth.value > 9) {
+ perfDepth.reason.Say(source,
+ "This construct does not contain a loop nest"_because_en_US);
+ }
+ }
+ semaDepth.value = perfDepth.value = 0;
}
if (!entry_->owner) {
return Depth{semaDepth, perfDepth};
}
if (parser::Unwrap<parser::DoConstruct>(entry_->owner)) {
- return Depth{plus(1, semaDepth), plus(1, perfDepth)};
+ return Depth{int64_t(1) + semaDepth, int64_t(1) + perfDepth};
}
auto &omp{DEREF(parser::Unwrap<parser::OpenMPLoopConstruct>(*entry_->owner))};
const parser::OmpDirectiveSpecification &beginSpec{omp.BeginDir()};
llvm::omp::Directive dir{beginSpec.DirId()};
- if (!IsTransformableLoop(omp)) {
- return Depth{0, 0};
+ bool isFullUnroll{IsFullUnroll(omp)};
+
+ // Check full unroll separately.
+ if (!isFullUnroll && !IsTransformableLoop(omp)) {
+ Reason reason;
+ reason.Say(beginSpec.DirName().source,
+ "This construct is not a DO-loop or a loop-nest-generating construct"_because_en_US);
+ return Depth{{0, reason}, {0, reason}};
}
switch (dir) {
@@ -1215,13 +1238,17 @@ LoopSequence::Depth LoopSequence::calculateDepths() const {
if (*required == -1 || *required == *nestedLength) {
return Depth{value, value};
}
- return Depth{1, 1};
+ Reason reason(std::move(range.reason));
+ reason.Say(beginSpec.DirName().source,
+ "%s construct results in a proper loop-sequence"_because_en_US,
+ GetUpperName(llvm::omp::Directive::OMPD_fuse, version_));
+ return Depth{{1, reason}, {1, reason}};
}
}
- return Depth{std::nullopt, std::nullopt};
+ return Depth{};
}
// FUSE cannot create a nest of depth > 1 without DEPTH clause.
- return Depth{1, 1};
+ return Depth{WithReason<int64_t>(1), WithReason<int64_t>(1)};
case llvm::omp::Directive::OMPD_interchange:
case llvm::omp::Directive::OMPD_nothing:
case llvm::omp::Directive::OMPD_reverse:
@@ -1234,13 +1261,18 @@ LoopSequence::Depth LoopSequence::calculateDepths() const {
// Return the number of arguments in the SIZES clause
size_t num{
parser::UnwrapRef<parser::OmpClause::Sizes>(clause->u).v.size()};
- return Depth{plus(num, semaDepth), plus(num, perfDepth)};
+ return Depth{//
+ static_cast<int64_t>(num) + semaDepth,
+ static_cast<int64_t>(num) + perfDepth};
}
// The SIZES clause is mandatory, if it's missing the result is unknown.
return {};
case llvm::omp::Directive::OMPD_unroll:
- if (IsFullUnroll(omp)) {
- return Depth{0, 0};
+ if (isFullUnroll) {
+ Reason reason;
+ reason.Say(beginSpec.DirName().source,
+ "Fully unrolled loop does not result in a loop nest"_because_en_US);
+ return Depth{{0, reason}, {0, reason}};
}
// If this is not a full unroll then look for a PARTIAL clause.
if (auto *clause{parser::omp::FindClause(
@@ -1258,9 +1290,12 @@ LoopSequence::Depth LoopSequence::calculateDepths() const {
// have either depth greater than 1: if it had a loop nested in it,
// then after unroll it will have at least two copies it it, making
// it a final loop.
- return {1, 1};
+ Reason reason;
+ reason.Say(beginSpec.DirName().source,
+ "Partially unrolled loop cannot form a nest of depth > 1"_because_en_US);
+ return {{1, reason}, {1, reason}};
}
- return Depth{std::nullopt, std::nullopt};
+ return Depth{};
default:
llvm_unreachable("Expecting loop-transforming construct");
}
@@ -1268,13 +1303,15 @@ LoopSequence::Depth LoopSequence::calculateDepths() const {
LoopSequence::Depth LoopSequence::getNestedDepths() const {
if (!isNest()) {
- return {std::nullopt, std::nullopt};
+ // If the current sequence is not a nest, it can still be a part of
+ // an enclosing nest.
+ return Depth{WithReason<int64_t>(0), WithReason<int64_t>(0)};
} else if (children_.empty()) {
// No children, but length == 1.
assert(entry_->owner &&
parser::Unwrap<parser::DoConstruct>(entry_->owner) &&
"Expecting DO construct");
- return Depth{0, 0};
+ return Depth{WithReason<int64_t>(0), WithReason<int64_t>(0)};
}
return children_.front().depth_;
}
diff --git a/flang/test/Semantics/OpenMP/do-collapse.f90 b/flang/test/Semantics/OpenMP/do-collapse.f90
index 70a84c333236a..9cac2c7f50a4d 100644
--- a/flang/test/Semantics/OpenMP/do-collapse.f90
+++ b/flang/test/Semantics/OpenMP/do-collapse.f90
@@ -29,6 +29,7 @@ program omp_doCollapse
!BECAUSE: COLLAPSE clause was specified with argument 2
!$omp parallel do collapse(2)
do i = 1, 3
+ !BECAUSE: This is not a valid intervening code
!ERROR: Loop control is not present in the DO LOOP
!ERROR: The associated loop of a loop-associated directive cannot be a DO without control.
do
diff --git a/flang/test/Semantics/OpenMP/do-concurrent-collapse.f90 b/flang/test/Semantics/OpenMP/do-concurrent-collapse.f90
index 3e382eb3cc4d4..b84d8d54a6629 100644
--- a/flang/test/Semantics/OpenMP/do-concurrent-collapse.f90
+++ b/flang/test/Semantics/OpenMP/do-concurrent-collapse.f90
@@ -6,6 +6,7 @@
! ERROR: DO CONCURRENT loops cannot be used with the COLLAPSE clause.
!$omp parallel do collapse(2)
do i = 1, 1
+ ! BECAUSE: This is not a valid intervening code
! ERROR: DO CONCURRENT loops cannot form part of a loop nest.
do concurrent (j = 1:2)
print *, j
@@ -37,6 +38,7 @@
! ERROR: DO CONCURRENT loops cannot be used with the COLLAPSE clause.
!$omp loop collapse(2)
do i = 1, 1
+ ! BECAUSE: This is not a valid intervening code
do concurrent (j = 1:2)
print *, j
end do
diff --git a/flang/test/Semantics/OpenMP/do08.f90 b/flang/test/Semantics/OpenMP/do08.f90
index 8ab02a0d9acbf..300485f067b1d 100644
--- a/flang/test/Semantics/OpenMP/do08.f90
+++ b/flang/test/Semantics/OpenMP/do08.f90
@@ -11,6 +11,7 @@ program omp
!BECAUSE: COLLAPSE clause was specified with argument 3
!$omp do collapse(3)
do i = 0, 10
+ !BECAUSE: This code prevents perfect nesting
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
if (i .lt. 1) cycle
do j = 0, 10
@@ -26,6 +27,7 @@ program omp
!$omp do collapse(3)
do i = 0, 10
do j = 0, 10
+ !BECAUSE: This code prevents perfect nesting
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
if (i .lt. 1) cycle
do k = 0, 10
@@ -39,6 +41,7 @@ program omp
!BECAUSE: COLLAPSE clause was specified with argument 2
!$omp do collapse(2)
do i = 0, 10
+ !BECAUSE: This code prevents perfect nesting
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
if (i .lt. 1) cycle
do j = 0, 10
@@ -54,6 +57,7 @@ program omp
!BECAUSE: COLLAPSE clause was specified with argument 2
!$omp do collapse(2)
foo: do i = 0, 10
+ !BECAUSE: This code prevents perfect nesting
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
if (i .lt. 1) cycle foo
do j = 0, 10
@@ -70,10 +74,11 @@ program omp
!$omp do collapse(3)
do 60 i=2,200,2
do j=1,10
+ !BECAUSE: This code prevents perfect nesting
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
- if(i==100) cycle
- do k=1,10
- print *,i
+ if (i == 100) cycle
+ do k = 1, 10
+ print *, i
end do
end do
60 continue
@@ -134,12 +139,13 @@ program omp
!$omp do collapse(2) ordered(3)
foo: do i = 0, 10
foo1: do j = 0, 10
- !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
- if (k .lt. 1) cycle foo
- foo2: do k = 0, 10
- print *, i, j, k
- end do foo2
- end do foo1
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ !BECAUSE: This code prevents perfect nesting
+ if (k .lt. 1) cycle foo
+ foo2: do k = 0, 10
+ print *, i, j, k
+ end do foo2
+ end do foo1
end do foo
!$omp end do
diff --git a/flang/test/Semantics/OpenMP/do13.f90 b/flang/test/Semantics/OpenMP/do13.f90
index 895724e0a10d5..b4b07432e3800 100644
--- a/flang/test/Semantics/OpenMP/do13.f90
+++ b/flang/test/Semantics/OpenMP/do13.f90
@@ -9,6 +9,7 @@ program omp
!BECAUSE: COLLAPSE clause was specified with argument 3
!$omp do collapse(3)
do i = 0, 10
+ !BECAUSE: This is not a valid intervening code
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
cycle
do j = 0, 10
@@ -24,6 +25,7 @@ program omp
!$omp do collapse(3)
do i = 0, 10
do j = 0, 10
+ !BECAUSE: This is not a valid intervening code
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
cycle
do k = 0, 10
@@ -37,6 +39,7 @@ program omp
!BECAUSE: COLLAPSE clause was specified with argument 2
!$omp do collapse(2)
do i = 0, 10
+ !BECAUSE: This is not a valid intervening code
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
cycle
do j = 0, 10
@@ -52,6 +55,7 @@ program omp
!BECAUSE: COLLAPSE clause was specified with argument 2
!$omp do collapse(2)
foo: do i = 0, 10
+ !BECAUSE: This is not a valid intervening code
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
cycle foo
do j = 0, 10
@@ -68,6 +72,7 @@ program omp
!$omp do collapse(3)
do 60 i=1,10
do j=1,10
+ !BECAUSE: This is not a valid intervening code
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
cycle
do k=1,10
@@ -185,7 +190,7 @@ program omp
!$omp end parallel
end do foo1
end do foo
-!$omp end parallel do
-!$omp end parallel
+ !$omp end parallel do
+ !$omp end parallel
end program omp
diff --git a/flang/test/Semantics/OpenMP/do15.f90 b/flang/test/Semantics/OpenMP/do15.f90
index 939d7bfde303e..00baa0c431c5f 100644
--- a/flang/test/Semantics/OpenMP/do15.f90
+++ b/flang/test/Semantics/OpenMP/do15.f90
@@ -9,6 +9,7 @@ program omp
!BECAUSE: COLLAPSE clause was specified with argument 3
!$omp do collapse(3)
do i = 0, 10
+ !BECAUSE: This code prevents perfect nesting
if (i .lt. 1) then
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
cycle
@@ -26,6 +27,7 @@ program omp
!$omp do collapse(3)
do i = 0, 10
do j = 0, 10
+ !BECAUSE: This code prevents perfect nesting
if (i .lt. 1) then
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
cycle
@@ -59,6 +61,7 @@ program omp
!$omp do collapse(3)
foo: do i = 0, 10
foo1: do j = 0, 10
+ !BECAUSE: This code prevents perfect nesting
if (i .lt. 1) then
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
cycle foo
diff --git a/flang/test/Semantics/OpenMP/do16.f90 b/flang/test/Semantics/OpenMP/do16.f90
index e671c73783e1c..35d94b17f3c68 100644
--- a/flang/test/Semantics/OpenMP/do16.f90
+++ b/flang/test/Semantics/OpenMP/do16.f90
@@ -9,6 +9,7 @@ program omp
!BECAUSE: COLLAPSE clause was specified with argument 3
!$omp do collapse(3)
do i = 0, 10
+ !BECAUSE: This code prevents perfect nesting
select case (i)
case(1)
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
@@ -27,6 +28,7 @@ program omp
!$omp do collapse(3)
do i = 0, 10
do j = 0, 10
+ !BECAUSE: This code prevents perfect nesting
select case (i)
case(1)
!ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
diff --git a/flang/test/Semantics/OpenMP/do22.f90 b/flang/test/Semantics/OpenMP/do22.f90
index dc38bd5d23253..a0502aee748ae 100644
--- a/flang/test/Semantics/OpenMP/do22.f90
+++ b/flang/test/Semantics/OpenMP/do22.f90
@@ -8,6 +8,7 @@ subroutine do_imperfectly_nested_before
!BECAUSE: COLLAPSE clause was specified with argument 2
!$omp do collapse(2)
do i = 1, 10
+ !BECAUSE: This code prevents perfect nesting
print *, i
do j = 1, 10
print *, i, j
@@ -27,6 +28,7 @@ subroutine do_imperfectly_nested_behind
do j = 1, 10
print *, i, j
end do
+ !BECAUSE: This code prevents perfect nesting
print *, i
end do
!$omp end do
diff --git a/flang/test/Semantics/OpenMP/tile07.f90 b/flang/test/Semantics/OpenMP/tile07.f90
index 9642fe10013fd..0c98f6856ff15 100644
--- a/flang/test/Semantics/OpenMP/tile07.f90
+++ b/flang/test/Semantics/OpenMP/tile07.f90
@@ -13,6 +13,7 @@ subroutine non_perfectly_nested_loop_behind
do j = 1, 42
print *, j
end do
+ !BECAUSE: This code prevents perfect nesting
print *, i
end do
end subroutine
@@ -26,6 +27,7 @@ subroutine non_perfectly_nested_loop_before
!BECAUSE: SIZES clause was specified with 2 arguments
!$omp tile sizes(2,2)
do i = 1, 5
+ !BECAUSE: This code prevents perfect nesting
print *, i
do j = 1, 42
print *, j
diff --git a/flang/test/Semantics/OpenMP/tile09.f90 b/flang/test/Semantics/OpenMP/tile09.f90
new file mode 100644
index 0000000000000..fc81d22e49b3d
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/tile09.f90
@@ -0,0 +1,63 @@
+! Testing the Semantics of tile
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=61
+
+subroutine f00
+ integer :: i, j
+ !ERROR: This construct requires a perfect nest of depth 2, but the associated nest is a perfect nest of depth 1
+ !BECAUSE: SIZES clause was specified with 2 arguments
+ !$omp tile sizes(2, 2)
+ do i = 1, 10
+ !BECAUSE: This construct is not a DO-loop or a loop-nest-generating construct
+ !$omp do
+ do j = 1, 10
+ end do
+ end do
+end
+
+subroutine f01
+ integer :: i, j
+ !ERROR: This construct requires a perfect nest of depth 2, but the associated nest is a perfect nest of depth 1
+ !BECAUSE: SIZES clause was specified with 2 arguments
+ !$omp tile sizes(2, 2)
+ do i = 1, 10
+ !BECAUSE: Fully unrolled loop does not result in a loop nest
+ !$omp unroll full
+ do j = 1, 10
+ end do
+ end do
+end
+
+subroutine f02
+ integer :: i, j
+ !ERROR: This construct requires a perfect nest of depth 2, but the associated nest is a perfect nest of depth 1
+ !BECAUSE: SIZES clause was specified with 2 arguments
+ !$omp tile sizes(2, 2)
+ !BECAUSE: Partially unrolled loop cannot form a nest of depth > 1
+ !$omp unroll partial
+ do i = 1, 10
+ do j = 1, 10
+ end do
+ end do
+end
+
+subroutine f03
+ integer :: i, j, k
+ !ERROR: This construct requires a perfect nest of depth 3, but the associated nest is a perfect nest of depth 1
+ !BECAUSE: SIZES clause was specified with 3 arguments
+ !$omp tile sizes(2, 2, 2)
+ do i = 1, 10
+ !BECAUSE: LOOPRANGE clause was specified with a count of 1 starting at loop 1
+ !BECAUSE: FUSE construct results in a proper loop-sequence
+ !$omp fuse depth(2) looprange(1, 1)
+ do j = 1, 10
+ do k = 1, 10
+ end do
+ end do
+ do j = 1, 10
+ do k = 1, 10
+ end do
+ end do
+ !$omp end fuse
+ end do
+end
+
More information about the flang-commits
mailing list