https://gcc.gnu.org/g:8576d0b2134f8ff0449e50813034db4c18a4b6ae

commit r17-3188-g8576d0b2134f8ff0449e50813034db4c18a4b6ae
Author: Paul-Antoine Arras <[email protected]>
Date:   Fri Aug 7 15:33:37 2026 +0200

    openmp: Adjust calls to OMPT variants depending on loop-end call
    
    When the inscan modifier is present on a for construct, a call to 
GOMP_loop_end
    (or one of its variants) is already emitted. The extra call to one of the
    *_worksharing_end functions, enabled by -fopenmp-ompt, is therefore 
redundant.
    
    Furthermore, even without -fopenmp-ompt, the inscan modifier implies a call 
to
    GOMP_loop_end which requires the start variant of 
GOMP_loop_static_worksharing.
    
    gcc/ChangeLog:
    
            * omp-expand.cc (expand_omp_for_static_nochunk,
            expand_omp_for_static_chunk): Adjust calls to OMPT variants with
            GOMP_loop_end.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/gomp/scan-8.c: New test.
            * c-c++-common/gomp/scan-9.c: New test.
    
    libgomp/ChangeLog:
    
            * loop.c (GOMP_loop_static_worksharing_start,
            GOMP_loop_static_worksharing_end): Update comments.

Diff:
---
 gcc/omp-expand.cc                        | 34 ++++++++++++++++++++++----------
 gcc/testsuite/c-c++-common/gomp/scan-8.c | 22 +++++++++++++++++++++
 gcc/testsuite/c-c++-common/gomp/scan-9.c | 21 ++++++++++++++++++++
 libgomp/loop.c                           |  6 ++++--
 4 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc
index d6c44ebdbe21..50b9d9817d0c 100644
--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -5278,6 +5278,12 @@ expand_omp_for_static_nochunk (struct omp_region *region,
   t = fold_convert (itype, t);
   n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
 
+  /* When GOMP_loop_end (or one of its variants) is emitted (e.g. with the
+     inscan modifier), which already implies the end of the scope, _start
+     variants of GOMP builtin calls have to be used and _end can be skipped.  
*/
+  bool has_gomp_loop_end = fd->have_reductemp
+                          || ((fd->have_pointer_condtemp || fd->have_scantemp)
+                              && !fd->have_nonctrl_scantemp);
   {
     /* Fetch the thread/team id and the number of threads/teams in a single
        call to GOMP_loop_static_worksharing or
@@ -5292,13 +5298,15 @@ expand_omp_for_static_nochunk (struct omp_region 
*region,
       {
       case GF_OMP_FOR_KIND_FOR:
        decl = builtin_decl_explicit (
-         flag_openmp_ompt ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START
-                          : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING);
+         flag_openmp_ompt || has_gomp_loop_end
+           ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START
+           : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING);
        break;
       case GF_OMP_FOR_KIND_DISTRIBUTE:
        decl = builtin_decl_explicit (
-         flag_openmp_ompt ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START
-                          : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING);
+         flag_openmp_ompt || has_gomp_loop_end
+           ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START
+           : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING);
        break;
       default:
        gcc_unreachable ();
@@ -5663,7 +5671,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
     }
 
   gsi = gsi_last_nondebug_bb (exit_bb);
-  if (flag_openmp_ompt)
+  if (flag_openmp_ompt && !has_gomp_loop_end)
     {
       /* Insert call to GOMP_*_static_worksharing_end at the end of exit_bb.
        */
@@ -6109,6 +6117,10 @@ expand_omp_for_static_chunk (struct omp_region *region,
   n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
                                true, GSI_SAME_STMT);
 
+  /* When GOMP_loop_end (or one of its variants) is emitted (e.g. with the
+     inscan modifier), which already implies the end of the scope, _start
+     variants of GOMP builtin calls have to be used and _end can be skipped.  
*/
+  bool has_gomp_loop_end = fd->have_reductemp || fd->have_pointer_condtemp;
   {
     /* Fetch the thread/team id and the number of threads/teams in a single
        call to GOMP_loop_static_worksharing or
@@ -6123,13 +6135,15 @@ expand_omp_for_static_chunk (struct omp_region *region,
       {
       case GF_OMP_FOR_KIND_FOR:
        decl = builtin_decl_explicit (
-         flag_openmp_ompt ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START
-                          : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING);
+         flag_openmp_ompt || has_gomp_loop_end
+           ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START
+           : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING);
        break;
       case GF_OMP_FOR_KIND_DISTRIBUTE:
        decl = builtin_decl_explicit (
-         flag_openmp_ompt ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START
-                          : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING);
+         flag_openmp_ompt || has_gomp_loop_end
+           ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START
+           : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING);
        break;
       default:
        gcc_unreachable ();
@@ -6420,7 +6434,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
     }
 
   gsi = gsi_last_nondebug_bb (exit_bb);
-  if (flag_openmp_ompt)
+  if (flag_openmp_ompt && !has_gomp_loop_end)
     {
       /* Insert call to GOMP_*_static_worksharing_end at the end of exit_bb.
        */
diff --git a/gcc/testsuite/c-c++-common/gomp/scan-8.c 
b/gcc/testsuite/c-c++-common/gomp/scan-8.c
new file mode 100644
index 000000000000..cff8c03b3495
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/scan-8.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fopenmp-ompt -fdump-tree-ompexp" } */
+
+/* Check that an extra, OMPT variant of GOMP_loop_end is not emitted when the
+   inscan modifier is present on the for construct.  */
+
+#define N 100
+
+void f(void) {
+    int a[N], b[N];
+    int x = 0;
+
+#pragma omp parallel for simd reduction(inscan, +: x)
+    for (int k = 0; k < N; k++) {
+        x += a[k];
+#pragma omp scan inclusive(x)
+        b[k] = x;
+    }
+}
+
+/* { dg-final { scan-tree-dump "__builtin_GOMP_loop_end_nowait \\(" "ompexp" } 
} */
+/* { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_end_nowait 
\\(\\);\[\t\n \]*__builtin_GOMP_loop_static_worksharing_end \\(\\);" "ompexp" } 
} */
diff --git a/gcc/testsuite/c-c++-common/gomp/scan-9.c 
b/gcc/testsuite/c-c++-common/gomp/scan-9.c
new file mode 100644
index 000000000000..f03355363394
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/scan-9.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-ompexp" } */
+
+/* Check that the start variant of GOMP_loop_static_worksharing is emitted
+   when the inscan modifier is present on the for construct.  */
+
+#define N 100
+
+void f(void) {
+    int a[N], b[N];
+    int x = 0;
+
+#pragma omp parallel for simd reduction(inscan, +: x)
+    for (int k = 0; k < N; k++) {
+        x += a[k];
+#pragma omp scan inclusive(x)
+        b[k] = x;
+    }
+}
+
+/* { dg-final { scan-tree-dump "__builtin_GOMP_loop_static_worksharing_start 
\\(" "ompexp" } } */
diff --git a/libgomp/loop.c b/libgomp/loop.c
index 0692663215fa..7474279fcd62 100644
--- a/libgomp/loop.c
+++ b/libgomp/loop.c
@@ -1201,7 +1201,8 @@ GOMP_loop_static_worksharing (unsigned long long niter
   return nthreads + tid * 1I;
 }
 
-/* OMPT variant enabled by -fopenmp-ompt.  */
+/* OMPT variant enabled by -fopenmp-ompt and when GOMP_loop_end is called
+   (e.g. with the inscan modifier).  */
 
 _Complex int
 GOMP_loop_static_worksharing_start (unsigned long long niter
@@ -1224,7 +1225,8 @@ GOMP_loop_static_worksharing_dispatch (unsigned long long 
start
                                       __attribute__ ((unused)))
 {}
 
-/* Stub for OMPT callback enabled by -fopenmp-ompt.  */
+/* Stub for OMPT callback enabled by -fopenmp-ompt, except when GOMP_loop_end 
is
+   already called (e.g. with the inscan modifier).  */
 
 void
 GOMP_loop_static_worksharing_end (void)

Reply via email to