[flang-commits] [flang] [flang] Fix crash when GoTo exits acc.loop region (PR #187613)
via flang-commits
flang-commits at lists.llvm.org
Thu Mar 19 22:10:56 PDT 2026
https://github.com/khaki3 updated https://github.com/llvm/llvm-project/pull/187613
>From dcdad97b8f4b60d55f32f07d7eeba95d63426bbb Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Thu, 19 Mar 2026 17:14:13 -0700
Subject: [PATCH 1/3] [flang] Fix crash when GoTo exits acc.loop region
When a GoTo inside an $Acc Loop Seq targets a label outside the
acc.loop's MLIR region, the lowering generated an illegal cross-region
cf.br. This caused runRegionDCE's recursive propagateLiveness to enter
a cyclic traversal through the dangling reference, overflowing the
compiler stack.
Fix by generating acc.yield (proper region exit) instead of cf.br when
the GoTo target block is in a different region than the current one.
This reuses the existing early-exit mechanism already used for RETURN
statements inside acc.loop.
Made-with: Cursor
---
flang/lib/Lower/Bridge.cpp | 11 ++++++++-
.../test/Lower/OpenACC/acc-loop-goto-exit.f90 | 24 +++++++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
create mode 100644 flang/test/Lower/OpenACC/acc-loop-goto-exit.f90
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 7459f814a0d4d..e14912017ae7d 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -6239,7 +6239,16 @@ class FirConverter : public Fortran::lower::AbstractConverter {
genConstructExitBranch(*getEval().controlSuccessor);
}
void genFIR(const Fortran::parser::GotoStmt &) {
- genConstructExitBranch(*getEval().controlSuccessor);
+ auto &targetEval = *getEval().controlSuccessor;
+ if (Fortran::lower::isInOpenACCLoop(*builder)) {
+ mlir::Block *targetBlock = targetEval.block;
+ mlir::Region *currentRegion = &builder->getRegion();
+ if (targetBlock && targetBlock->getParent() != currentRegion) {
+ mlir::acc::YieldOp::create(*builder, toLocation());
+ return;
+ }
+ }
+ genConstructExitBranch(targetEval);
}
// Nop statements - No code, or code is generated at the construct level.
diff --git a/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90 b/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90
new file mode 100644
index 0000000000000..88fc30d79c3d1
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90
@@ -0,0 +1,24 @@
+! Test that GoTo exiting an acc.loop seq region generates acc.yield
+! instead of an illegal cross-region cf.br that would crash the compiler.
+! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func.func @_QPfoo
+subroutine foo(N, A, B)
+ implicit real*8 (a-h, o-z)
+ !$acc routine gang
+ dimension A(*), B(*)
+ !$acc loop gang vector
+ do 100 i = 1, N
+ ! CHECK: acc.loop gang vector
+ ! CHECK: acc.loop
+ !$acc loop seq
+ do 10 j = 1, 1000
+ if (A(i) .gt. B(i)) goto 20
+10 continue
+ ! The GoTo crossing the acc.loop region boundary must generate
+ ! acc.yield (not cf.br) to properly exit the inner acc.loop.
+ ! CHECK: acc.yield
+ ! CHECK: acc.yield
+20 B(i) = A(i)
+100 continue
+end subroutine
>From 3cf4d749406a8c2a153a65157d94d1505aaa4fa0 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Thu, 19 Mar 2026 22:03:36 -0700
Subject: [PATCH 2/3] [flang] Update lit test: use -emit-hlfir and fix CHECK
lines
Made-with: Cursor
---
flang/test/Lower/OpenACC/acc-loop-goto-exit.f90 | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90 b/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90
index 88fc30d79c3d1..fc7b036b0cef1 100644
--- a/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90
+++ b/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90
@@ -1,6 +1,6 @@
! Test that GoTo exiting an acc.loop seq region generates acc.yield
! instead of an illegal cross-region cf.br that would crash the compiler.
-! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s
+! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
! CHECK-LABEL: func.func @_QPfoo
subroutine foo(N, A, B)
@@ -10,15 +10,17 @@ subroutine foo(N, A, B)
!$acc loop gang vector
do 100 i = 1, N
! CHECK: acc.loop gang vector
- ! CHECK: acc.loop
+ ! CHECK: acc.loop {{.*}} {
!$acc loop seq
do 10 j = 1, 1000
if (A(i) .gt. B(i)) goto 20
10 continue
! The GoTo crossing the acc.loop region boundary must generate
- ! acc.yield (not cf.br) to properly exit the inner acc.loop.
+ ! acc.yield to properly exit the inner acc.loop, not an illegal
+ ! cross-region cf.br that would crash the compiler.
! CHECK: acc.yield
! CHECK: acc.yield
+ ! CHECK: }
20 B(i) = A(i)
100 continue
end subroutine
>From 17b8cc322a7b5680b42779134c79def31fb10957 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Thu, 19 Mar 2026 22:10:45 -0700
Subject: [PATCH 3/3] [flang] Improve lit test: use -emit-hlfir, check
seq+unstructured attrs
Made-with: Cursor
---
flang/test/Lower/OpenACC/acc-loop-goto-exit.f90 | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90 b/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90
index fc7b036b0cef1..ff6d7ca4aef25 100644
--- a/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90
+++ b/flang/test/Lower/OpenACC/acc-loop-goto-exit.f90
@@ -9,18 +9,18 @@ subroutine foo(N, A, B)
dimension A(*), B(*)
!$acc loop gang vector
do 100 i = 1, N
- ! CHECK: acc.loop gang vector
- ! CHECK: acc.loop {{.*}} {
!$acc loop seq
do 10 j = 1, 1000
if (A(i) .gt. B(i)) goto 20
10 continue
- ! The GoTo crossing the acc.loop region boundary must generate
- ! acc.yield to properly exit the inner acc.loop, not an illegal
- ! cross-region cf.br that would crash the compiler.
- ! CHECK: acc.yield
- ! CHECK: acc.yield
- ! CHECK: }
20 B(i) = A(i)
100 continue
end subroutine
+
+! Verify the inner acc.loop has seq and unstructured attributes,
+! and that it contains acc.yield (from the GoTo cross-region exit).
+! CHECK: acc.loop gang vector
+! CHECK: acc.loop
+! CHECK: acc.yield
+! CHECK: acc.yield
+! CHECK: } attributes {seq = [#acc.device_type<none>], unstructured}
More information about the flang-commits
mailing list