[flang-commits] [flang] [Flang][OpenMP] Emit TODO for non-rectangular collapsed loop nests (PR #205558)
CHANDRA GHALE via flang-commits
flang-commits at lists.llvm.org
Wed Jun 24 06:32:17 PDT 2026
https://github.com/chandraghale created https://github.com/llvm/llvm-project/pull/205558
Non-rectangular loop nests (where an inner loop bound depends on an outer IV) with collapse currently generate incorrect code that segfaults at runtime, since OpenMPIRBuilder's collapseLoops assumes rectangular iteration spaces.
Added a check during lowering to detect the non-rectangular case and emit a clear "not yet implemented" error instead of silently producing broken code.
minimal reproducer :
```
program repro
implicit none
integer, parameter :: N = 10
integer :: arr(N,N), i, j
arr = 0
!$omp parallel do collapse(2)
do i = 1, N
do j = 1, i ! non-rectangular: upper bound depends on i
arr(j,i) = 1
end do
end do
if (sum(arr) /= N*(N+1)/2) then
print , "FAIL: sum =", sum(arr), " expected", N(N+1)/2
stop 1
end if
print *, "PASS"
end program
```
```
flang -O1 -fopenmp -fopenmp-version=50 repro.f90 && ./a.out
Segmentation fault (signal 11)
```
>From e4c862bc3c0643571f1621e866d423011e16177f Mon Sep 17 00:00:00 2001
From: Chandra Ghale <ghale at pe34genoa.hpc.amslabs.hpecorp.net>
Date: Wed, 24 Jun 2026 08:28:11 -0500
Subject: [PATCH] emit todo for non-rectangular collapsed loop nests
---
flang/lib/Lower/OpenMP/Utils.cpp | 32 ++++++++++++
.../Lower/OpenMP/non-rectangular-collapse.f90 | 52 +++++++++++++++++++
2 files changed, 84 insertions(+)
create mode 100644 flang/test/Lower/OpenMP/non-rectangular-collapse.f90
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index 7a532e10f1a1e..1e6f32088a379 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -800,6 +800,38 @@ void collectLoopRelatedInfo(
const parser::LoopControl::Bounds *bounds =
std::get_if<parser::LoopControl::Bounds>(&loopControl->u);
assert(bounds && "Expected bounds for worksharing do loop");
+ // Check for non-rectangular loops: if any bound of this loop references
+ // an iteration variable from an enclosing collapsed loop, this is a
+ // non-rectangular loop nest which is not yet supported by the
+ // OpenMPIRBuilder's collapseLoops.
+ if (!iv.empty()) {
+ auto referencesOuterIV = [&iv](const semantics::SomeExpr &expr) -> bool {
+ for (const semantics::SymbolRef &sym :
+ evaluate::GetSymbolVector(expr)) {
+ for (const semantics::Symbol *outerIV : iv) {
+ if (&sym->GetUltimate() == &outerIV->GetUltimate())
+ return true;
+ }
+ }
+ return false;
+ };
+ if (const auto *lowerExpr = semantics::GetExpr(bounds->Lower()))
+ if (referencesOuterIV(*lowerExpr))
+ TODO(currentLocation,
+ "Non-rectangular loop nests with COLLAPSE are not yet "
+ "supported");
+ if (const auto *upperExpr = semantics::GetExpr(bounds->Upper()))
+ if (referencesOuterIV(*upperExpr))
+ TODO(currentLocation,
+ "Non-rectangular loop nests with COLLAPSE are not yet "
+ "supported");
+ if (auto &step = bounds->Step())
+ if (const auto *stepExpr = semantics::GetExpr(step))
+ if (referencesOuterIV(*stepExpr))
+ TODO(currentLocation,
+ "Non-rectangular loop nests with COLLAPSE are not yet "
+ "supported");
+ }
lower::StatementContext stmtCtx;
result.loopLowerBounds.push_back(fir::getBase(
converter.genExprValue(*semantics::GetExpr(bounds->Lower()), stmtCtx)));
diff --git a/flang/test/Lower/OpenMP/non-rectangular-collapse.f90 b/flang/test/Lower/OpenMP/non-rectangular-collapse.f90
new file mode 100644
index 0000000000000..17fbbd1e49084
--- /dev/null
+++ b/flang/test/Lower/OpenMP/non-rectangular-collapse.f90
@@ -0,0 +1,52 @@
+! Test that non-rectangular collapsed loop nests produce a clear TODO error
+! rather than generating incorrect code that crashes at runtime.
+
+! RUN: not %flang_fc1 -emit-fir -fopenmp -fopenmp-version=50 %s -o - 2>&1 | FileCheck %s
+
+! Non-rectangular: upper bound of inner loop depends on outer IV
+subroutine non_rect_ub(N)
+ implicit none
+ integer, intent(in) :: N
+ integer :: arr(N,N)
+ integer :: i, j
+
+ !$omp parallel do collapse(2)
+ do i = 1, N
+ do j = 1, i
+ arr(j,i) = 1
+ end do
+ end do
+end subroutine
+
+! CHECK: not yet implemented: Non-rectangular loop nests with COLLAPSE are not yet supported
+
+! Non-rectangular: lower bound of inner loop depends on outer IV
+subroutine non_rect_lb(N)
+ implicit none
+ integer, intent(in) :: N
+ integer :: arr(N,N)
+ integer :: i, j
+
+ !$omp parallel do collapse(2)
+ do i = 1, N
+ do j = i, N
+ arr(j,i) = 1
+ end do
+ end do
+end subroutine
+
+! Non-rectangular: step of inner loop depends on outer IV
+subroutine non_rect_step(N)
+ implicit none
+ integer, intent(in) :: N
+ integer :: arr(N,N)
+ integer :: i, j
+
+ !$omp parallel do collapse(2)
+ do i = 1, N
+ do j = 1, N, i
+ arr(j,i) = 1
+ end do
+ end do
+end subroutine
+
More information about the flang-commits
mailing list