]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
OpenMP: Fix bogus diagnostics with intervening code [PR121452]
authorPaul-Antoine Arras <parras@baylibre.com>
Tue, 21 Oct 2025 07:48:23 +0000 (09:48 +0200)
committerPaul-Antoine Arras <parras@baylibre.com>
Fri, 24 Oct 2025 09:35:59 +0000 (11:35 +0200)
The introduction in r14-3488-ga62c8324e7e31a of OMP_STRUCTURED_BLOCK (to
diagnose invalid intervening code) caused a regression rejecting the valid use
of the Fortran CONTINUE statement to end a collapsed loop.
This patch fixes the incorrect error checking in the OMP lowering pass. It also
fixes a check in the Fortran front end that erroneously rejects a similar
statement in an ordered loop.

Co-authored by: Tobias Burnus <tburnus@baylibre.com>

PR fortran/121452

gcc/fortran/ChangeLog:

* openmp.cc (resolve_omp_do): Allow CONTINUE as end statement of a
perfectly nested loop.

gcc/ChangeLog:

* omp-low.cc (check_omp_nesting_restrictions): Accept an
OMP_STRUCTURED_BLOCK in a collapsed simd region and in an ordered loop.

gcc/testsuite/ChangeLog:

* c-c++-common/gomp/pr121452-1.c: New test.
* c-c++-common/gomp/pr121452-2.c: New test.
* gfortran.dg/gomp/pr121452-1.f90: New test.
* gfortran.dg/gomp/pr121452-2.f90: New test.
* gfortran.dg/gomp/pr121452-3.f90: New test.

gcc/fortran/openmp.cc
gcc/omp-low.cc
gcc/testsuite/c-c++-common/gomp/pr121452-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/pr121452-2.c [new file with mode: 0644]
gcc/testsuite/gfortran.dg/gomp/pr121452-1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/gomp/pr121452-2.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/gomp/pr121452-3.f90 [new file with mode: 0644]

index 8cea7242de22ac7e127aecbe42e81c708d8a3e9b..357e6a7f09d0cb84aa168dfbe8daf2ea38468f04 100644 (file)
@@ -12150,7 +12150,8 @@ resolve_omp_do (gfc_code *code)
                     name, i, &code->loc);
          goto fail;
        }
-      else if (next != do_code->block->next || next->next)
+      else if (next != do_code->block->next
+              || (next->next && next->next->op != EXEC_CONTINUE))
        /* Imperfectly nested loop found.  */
        {
          /* Only diagnose violation of imperfect nesting constraints once.  */
index 6b0135ecdd971b2a45ed528ac945a8854f21e796..d36756e33a5aff12bfb3392914d4b3acb6747bea 100644 (file)
@@ -3307,7 +3307,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
            }
          else if (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
                   || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE
-                  || gimple_code (stmt) == GIMPLE_OMP_SCAN)
+                  || gimple_code (stmt) == GIMPLE_OMP_SCAN
+                  || gimple_code (stmt) == GIMPLE_OMP_STRUCTURED_BLOCK)
            return true;
          else if (gimple_code (stmt) == GIMPLE_OMP_FOR
                   && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
@@ -3337,7 +3338,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
               && gimple_code (stmt) != GIMPLE_OMP_PARALLEL
               && (gimple_code (stmt) != GIMPLE_OMP_FOR
                   || gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_SIMD)
-              && gimple_code (stmt) != GIMPLE_OMP_SCAN)
+              && gimple_code (stmt) != GIMPLE_OMP_SCAN
+              && gimple_code (stmt) != GIMPLE_OMP_STRUCTURED_BLOCK)
        {
          if (ctx->loop_p)
            error_at (gimple_location (stmt),
diff --git a/gcc/testsuite/c-c++-common/gomp/pr121452-1.c b/gcc/testsuite/c-c++-common/gomp/pr121452-1.c
new file mode 100644 (file)
index 0000000..d605919
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-original" } */
+
+/* Check that the OMP_STRUCTURED_BLOCK that wraps intervening code is accepted.
+ */
+
+void f(int *A, int *B, int *C)
+{
+  #pragma omp for simd collapse(2)
+  for (int i=0; i < 1; i++) {
+    for (int j=0; j < 1; j++)
+      A[i] += B[j];
+    C[i] = 4;
+  }
+}
+
+/* { dg-final { scan-tree-dump "#pragma omp __structured_block" "original" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/pr121452-2.c b/gcc/testsuite/c-c++-common/gomp/pr121452-2.c
new file mode 100644 (file)
index 0000000..35fb1c1
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-original" } */
+
+/* Check that the OMP_STRUCTURED_BLOCK that wraps intervening code is accepted.
+ */
+
+void f(int *A, int *B, int *C)
+{
+  #pragma omp loop bind(teams) order(concurrent) collapse(2)
+  for (int i=0; i < 1; i++) {
+    for (int j=0; j < 1; j++)
+      A[i] += B[j];
+    C[i] = 4;
+  }
+}
+
+/* { dg-final { scan-tree-dump "#pragma omp __structured_block" "original" } } */
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr121452-1.f90 b/gcc/testsuite/gfortran.dg/gomp/pr121452-1.f90
new file mode 100644 (file)
index 0000000..60697c9
--- /dev/null
@@ -0,0 +1,18 @@
+! { dg-do compile }
+
+! Check that the front end acccepts a CONTINUE statement
+! inside an ordered loop.
+
+implicit none
+integer :: i, j
+integer :: A(5,5), B(5,5) = 1
+
+!$omp do ordered(2)
+   do 10 i = 1, 5
+     do 20 j = 1, 5
+       A(i,j) = B(i,j)
+20   continue
+10 continue
+
+if (any(A /= 1)) stop 1
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr121452-2.f90 b/gcc/testsuite/gfortran.dg/gomp/pr121452-2.f90
new file mode 100644 (file)
index 0000000..ab020d4
--- /dev/null
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+
+! Check that the OMP_STRUCTURED_BLOCK that wraps intervening code is accepted by
+! the OMP lowering pass.
+
+implicit none
+integer :: i, j, x
+integer :: A(5,5), B(5,5) = 1
+
+!$omp simd collapse(2)
+   do i = 1, 5
+     do j = 1, 5
+       A(i,j) = B(i,j)
+    end do
+    x = 1 ! intervening code
+  end do
+
+if (any(A /= 1)) stop 1
+end
+
+! { dg-final { scan-tree-dump "#pragma omp __structured_block" "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr121452-3.f90 b/gcc/testsuite/gfortran.dg/gomp/pr121452-3.f90
new file mode 100644 (file)
index 0000000..605f92c
--- /dev/null
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+
+! Check that the OMP_STRUCTURED_BLOCK that wraps intervening code is accepted by
+! the OMP lowering pass.
+
+
+implicit none
+integer :: i, j
+integer :: A(5,5), B(5,5) = 1
+
+!$omp simd collapse(2)
+   do 10 i = 1, 5
+     do 20 j = 1, 5
+       A(i,j) = B(i,j)
+20   continue
+10 continue
+
+if (any(A /= 1)) stop 1
+end
+
+! { dg-final { scan-tree-dump "#pragma omp __structured_block" "original" } }