omp-low.c (check_omp_nesting_restrictions): Allow cancel or cancellation point with...
authorJakub Jelinek <jakub@redhat.com>
Sun, 2 Dec 2018 12:48:42 +0000 (13:48 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sun, 2 Dec 2018 12:48:42 +0000 (13:48 +0100)
* omp-low.c (check_omp_nesting_restrictions): Allow cancel or
cancellation point with taskgroup clause inside of taskloop.  Consider
a taskloop construct without nogroup clause as implicit taskgroup for
diagnostics if cancel/cancellation point with taskgroup clause is
closely nested inside of taskgroup region.

* c-c++-common/gomp/cancel-1.c (f2): Add various taskloop related
tests.

* testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c: New test.

From-SVN: r266722

gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/gomp/cancel-1.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c [new file with mode: 0644]

index e80e1dd..a13d8a5 100644 (file)
@@ -1,5 +1,11 @@
 2018-12-02  Jakub Jelinek  <jakub@redhat.com>
 
+       * omp-low.c (check_omp_nesting_restrictions): Allow cancel or
+       cancellation point with taskgroup clause inside of taskloop.  Consider
+       a taskloop construct without nogroup clause as implicit taskgroup for
+       diagnostics if cancel/cancellation point with taskgroup clause is
+       closely nested inside of taskgroup region.
+
        PR sanitizer/88291
        * asan.c (asan_clear_shadow): Move assert that len is multiple of 4
        to the start of the function.
index ca78d7a..b406ce7 100644 (file)
@@ -2744,7 +2744,10 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
              kind = "sections";
              break;
            case 8:
-             if (gimple_code (ctx->stmt) != GIMPLE_OMP_TASK)
+             if (!is_task_ctx (ctx)
+                 && (!is_taskloop_ctx (ctx)
+                     || ctx->outer == NULL
+                     || !is_task_ctx (ctx->outer)))
                bad = "#pragma omp task";
              else
                {
@@ -2767,6 +2770,17 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
                                    "nested inside of %<taskgroup%> region",
                                    construct);
                          return false;
+                       case GIMPLE_OMP_TASK:
+                         if (gimple_omp_task_taskloop_p (octx->stmt)
+                             && octx->outer
+                             && is_taskloop_ctx (octx->outer))
+                           {
+                             tree clauses
+                               = gimple_omp_for_clauses (octx->outer->stmt);
+                             if (!omp_find_clause (clauses, OMP_CLAUSE_NOGROUP))
+                               break;
+                           }
+                         continue;
                        default:
                          continue;
                        }
index 916cb55..89dc430 100644 (file)
@@ -1,5 +1,8 @@
 2018-12-02  Jakub Jelinek  <jakub@redhat.com>
 
+       * c-c++-common/gomp/cancel-1.c (f2): Add various taskloop related
+       tests.
+
        PR sanitizer/88291
        * c-c++-common/asan/pr88291.c: New test.
 
index d26fcf1..03aedeb 100644 (file)
@@ -95,6 +95,40 @@ f2 (void)
       #pragma omp cancellation point sections  /* { dg-error "not closely nested inside" } */
       #pragma omp cancellation point taskgroup
     }
+    #pragma omp taskloop
+    for (i = 0; i < 10; i++)
+      {
+        #pragma omp cancel parallel            /* { dg-error "not closely nested inside" } */
+        #pragma omp cancel for                 /* { dg-error "not closely nested inside" } */
+        #pragma omp cancel sections            /* { dg-error "not closely nested inside" } */
+        #pragma omp cancel taskgroup
+        #pragma omp cancellation point parallel        /* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point for     /* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point sections        /* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point taskgroup
+       #pragma omp task
+       {
+         #pragma omp cancellation point taskgroup
+         #pragma omp cancel taskgroup
+       }
+      }
+    #pragma omp taskloop nogroup
+    for (i = 0; i < 10; i++)
+      {
+        #pragma omp cancel parallel            /* { dg-error "not closely nested inside" } */
+        #pragma omp cancel for                 /* { dg-error "not closely nested inside" } */
+        #pragma omp cancel sections            /* { dg-error "not closely nested inside" } */
+        #pragma omp cancel taskgroup           /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+        #pragma omp cancellation point parallel        /* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point for     /* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point sections        /* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point taskgroup/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+       #pragma omp task
+       {
+         #pragma omp cancellation point taskgroup/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+         #pragma omp cancel taskgroup          /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+       }
+      }
     #pragma omp taskgroup
     {
       #pragma omp task
@@ -105,6 +139,17 @@ f2 (void)
          #pragma omp cancel taskgroup
        }
       }
+      #pragma omp taskloop nogroup
+      for (i = 0; i < 10; i++)
+       {
+         #pragma omp task
+         {
+           #pragma omp cancellation point taskgroup
+           #pragma omp cancel taskgroup
+         }
+         #pragma omp cancellation point taskgroup
+         #pragma omp cancel taskgroup
+       }
     }
     #pragma omp taskgroup
     {
@@ -115,6 +160,18 @@ f2 (void)
          #pragma omp cancel taskgroup          /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
          #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
        }
+       #pragma omp taskloop
+       for (i = 0; i < 10; i++)
+         {
+           #pragma omp cancel taskgroup
+           #pragma omp cancellation point taskgroup
+         }
+       #pragma omp taskloop nogroup
+       for (i = 0; i < 10; i++)
+         {
+           #pragma omp cancel taskgroup             /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+           #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+         }
       }
       #pragma omp target
       {
@@ -144,6 +201,45 @@ f2 (void)
        }
       }
     }
+    #pragma omp taskloop
+    for (i = 0; i < 10; i++)
+      {
+       #pragma omp parallel
+       {
+         #pragma omp task
+         {
+           #pragma omp cancel taskgroup             /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+           #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+         }
+       }
+        #pragma omp target
+       {
+         #pragma omp task
+         {
+           #pragma omp cancel taskgroup             /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+           #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+         }
+       }
+       #pragma omp target
+       #pragma omp teams
+       #pragma omp distribute
+       for (j = 0; j < 10; j++)
+         {
+           #pragma omp task
+           {
+             #pragma omp cancel taskgroup      /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+             #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+           }
+         }
+       #pragma omp target data map(i)
+       {
+         #pragma omp task
+         {
+           #pragma omp cancel taskgroup
+           #pragma omp cancellation point taskgroup
+         }
+       }
+      }
     #pragma omp for
     for (i = 0; i < 10; i++)
       {
index d095a19..9a6d9a3 100644 (file)
@@ -1,3 +1,7 @@
+2018-12-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c: New test.
+
 2018-11-30  Cesar Philippidis  <cesar@codesourcery.com>
 
        PR libgomp/88288
diff --git a/libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c b/libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c
new file mode 100644 (file)
index 0000000..341bfb8
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var OMP_CANCELLATION "true" } */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <omp.h>
+
+int
+main ()
+{
+  int i;
+  #pragma omp parallel
+  {
+    int c = 0;
+    #pragma omp barrier
+    #pragma omp master taskloop num_tasks (25) firstprivate (c)
+    for (i = 0; i < 50; i++)
+      {
+        if (c && omp_get_cancellation ())
+         abort ();
+       #pragma omp cancellation point taskgroup
+       usleep (30);
+       if (i > 10)
+         c = 1;
+       #pragma omp cancel taskgroup if (i > 10)
+       if (i > 10 && omp_get_cancellation ())
+         abort ();
+      }
+    usleep (10);
+  }
+  return 0;
+}