[flang-commits] [flang] [flang][openacc] Recurse into OpenACC constructs when matching labeled DO (PR #217984)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Fri Aug 21 10:17:35 PDT 2026


https://github.com/clementval created https://github.com/llvm/llvm-project/pull/217984

GetFinalLabel() already walked an OpenACC loop or combined construct to
find a shared terminating label, but the Block walker did not recurse
into nested OpenACC constructs. Three labeled DO loops that share one
terminator, each associated with its own !$acc loop, then failed with
"Label is not in DO loop scope".

Look through OpenACCConstruct in GetFinalLabel(const Block &) the same
way OpenMP constructs are already handled.

>From 988e76b6be59fd78068d30f336db04704da5d7bf Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Fri, 21 Aug 2026 10:06:19 -0700
Subject: [PATCH] [flang][openacc] Recurse into OpenACC constructs when
 matching labeled DO

---
 flang/lib/Parser/tools.cpp         |  2 ++
 flang/test/Parser/acc-label-do.f90 | 32 ++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/flang/lib/Parser/tools.cpp b/flang/lib/Parser/tools.cpp
index d0c919d07f917..ab73d1d86b79e 100644
--- a/flang/lib/Parser/tools.cpp
+++ b/flang/lib/Parser/tools.cpp
@@ -223,6 +223,8 @@ std::optional<Label> GetFinalLabel(const Block &x) {
     const ExecutionPartConstruct &last{x.back()};
     if (auto *omp{Unwrap<OpenMPConstruct>(last)}) {
       return GetFinalLabel(*omp);
+    } else if (auto *acc{Unwrap<OpenACCConstruct>(last)}) {
+      return GetFinalLabel(*acc);
     } else if (auto *doLoop{Unwrap<DoConstruct>(last)}) {
       return GetFinalLabel(std::get<Block>(doLoop->t));
     } else {
diff --git a/flang/test/Parser/acc-label-do.f90 b/flang/test/Parser/acc-label-do.f90
index e9de2fe59d9b2..e8b2995e04a7e 100644
--- a/flang/test/Parser/acc-label-do.f90
+++ b/flang/test/Parser/acc-label-do.f90
@@ -48,6 +48,23 @@ subroutine nested_shared_label(a, n)
 !$acc end kernels
 end
 
+! Same, with three levels of nesting: the label of the innermost loop is
+! reached through two OpenACC LOOP constructs.
+
+subroutine triple_shared_label(a, c, n, k)
+  integer :: i, j, m, n, k
+  real :: a(n), c(n,k)
+!$acc kernels
+!$acc loop independent
+  do 250 m = 1, n
+!$acc loop independent
+    do 250 j = 1, k
+!$acc loop gang vector
+      do 250 i = 1, n
+250     a(i) = a(i) + c(i,j)
+!$acc end kernels
+end
+
 !UNPARSE: SUBROUTINE nested_shared_label (a, n)
 !UNPARSE: !$ACC KERNELS
 !UNPARSE: !$ACC LOOP INDEPENDENT
@@ -81,3 +98,18 @@ subroutine nested_shared_label(a, n)
 !PARSE-TREE: | | | | | | | EndDoStmt ->
 !PARSE-TREE: | | | | EndDoStmt ->
 !PARSE-TREE: | AccEndBlockDirective -> AccBlockDirective -> llvm::acc::Directive = kernels
+
+!UNPARSE: SUBROUTINE triple_shared_label (a, c, n, k)
+!UNPARSE: !$ACC KERNELS
+!UNPARSE: !$ACC LOOP INDEPENDENT
+!UNPARSE:  DO m=1_4,n
+!UNPARSE: !$ACC LOOP INDEPENDENT
+!UNPARSE:   DO j=1_4,k
+!UNPARSE: !$ACC LOOP GANG VECTOR
+!UNPARSE:    DO i=1_4,n
+!UNPARSE:     250
+!UNPARSE:    END DO
+!UNPARSE:   END DO
+!UNPARSE:  END DO
+!UNPARSE: !$ACC END KERNELS
+!UNPARSE: END SUBROUTINE



More information about the flang-commits mailing list