Hi!

This patch deals with 2 issues:
1) the gimplifier couldn't differentiate between
 #pragma omp parallel master
 #pragma omp taskloop simd
and
 #pragma omp parallel master taskloop simd
when there is a significant difference for clause handling between
the two; as master construct doesn't have any clauses, we don't currently
represent it during gimplification by an gimplification omp context at all,
so this patch makes sure we don't set OMP_PARALLEL_COMBINED on parallel master
when not combined further.  If we ever add a separate master context during
gimplification, we'd use ORT_COMBINED_MASTER vs. ORT_MASTER (or MASKED 
probably).
2) lastprivate when combined with target should be map(tofrom:) on the target,
this change handles it only when not combined with firstprivate though, that
will need further work (similarly to linear or reduction).

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

2021-05-19  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/99928
        * tree.h (OMP_MASTER_COMBINED): Define.
        * gimplify.c (gimplify_scan_omp_clauses): Rewrite lastprivate
        handling for outer combined/composite constructs to a loop.
        Handle lastprivate on combined target.
        (gimplify_expr): Formatting fix.
c/
        * c-parser.c (c_parser_omp_master): Set OMP_MASTER_COMBINED on
        master when combined with taskloop.
        (c_parser_omp_parallel): Don't set OMP_PARALLEL_COMBINED on
        parallel master when not combined with taskloop.
cp/
        * parser.c (cp_parser_omp_master): Set OMP_MASTER_COMBINED on
        master when combined with taskloop.
        (cp_parser_omp_parallel): Don't set OMP_PARALLEL_COMBINED on
        parallel master when not combined with taskloop.
testsuite/
        * c-c++-common/gomp/pr99928-2.c: Remove all xfails.
        * c-c++-common/gomp/pr99928-12.c: New test.

--- gcc/tree.h.jj       2021-05-10 12:22:30.000000000 +0200
+++ gcc/tree.h  2021-05-18 16:03:19.147351858 +0200
@@ -1502,6 +1502,11 @@ class auto_suppress_location_wrappers
 #define OMP_TARGET_COMBINED(NODE) \
   (OMP_TARGET_CHECK (NODE)->base.private_flag)
 
+/* True on an OMP_MASTER statement if it represents an explicit
+   combined master constructs.  */
+#define OMP_MASTER_COMBINED(NODE) \
+  (OMP_MASTER_CHECK (NODE)->base.private_flag)
+
 /* Memory order for OMP_ATOMIC*.  */
 #define OMP_ATOMIC_MEMORY_ORDER(NODE) \
   (TREE_RANGE_CHECK (NODE, OMP_ATOMIC, \
--- gcc/gimplify.c.jj   2021-05-13 16:53:01.589688308 +0200
+++ gcc/gimplify.c      2021-05-18 17:55:04.524799739 +0200
@@ -8642,75 +8642,48 @@ gimplify_scan_omp_clauses (tree *list_p,
            }
          if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
            flags |= GOVD_LASTPRIVATE_CONDITIONAL;
-         if (outer_ctx
-             && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
-                 || ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
-                     == ORT_COMBINED_TEAMS))
-             && splay_tree_lookup (outer_ctx->variables,
-                                   (splay_tree_key) decl) == NULL)
-           {
-             omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
-             if (outer_ctx->outer_context)
-               omp_notice_variable (outer_ctx->outer_context, decl, true);
-           }
-         else if (outer_ctx
-                  && (outer_ctx->region_type & ORT_TASK) != 0
-                  && outer_ctx->combined_loop
-                  && splay_tree_lookup (outer_ctx->variables,
-                                        (splay_tree_key) decl) == NULL)
-           {
-             omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
-             if (outer_ctx->outer_context)
-               omp_notice_variable (outer_ctx->outer_context, decl, true);
-           }
-         else if (outer_ctx
-                  && (outer_ctx->region_type == ORT_WORKSHARE
-                      || outer_ctx->region_type == ORT_ACC)
-                  && outer_ctx->combined_loop
-                  && splay_tree_lookup (outer_ctx->variables,
-                                        (splay_tree_key) decl) == NULL
-                  && !omp_check_private (outer_ctx, decl, false))
-           {
-             omp_add_variable (outer_ctx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
-             if (outer_ctx->outer_context
-                 && (outer_ctx->outer_context->region_type
-                     == ORT_COMBINED_PARALLEL)
-                 && splay_tree_lookup (outer_ctx->outer_context->variables,
+         struct gimplify_omp_ctx *octx;
+         for (octx = outer_ctx; octx; octx = octx->outer_context)
+           {
+             if ((octx->region_type == ORT_COMBINED_PARALLEL
+                  || ((octx->region_type & ORT_COMBINED_TEAMS)
+                       == ORT_COMBINED_TEAMS))
+                 && splay_tree_lookup (octx->variables,
                                        (splay_tree_key) decl) == NULL)
                {
-                 struct gimplify_omp_ctx *octx = outer_ctx->outer_context;
                  omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
-                 if (octx->outer_context)
-                   {
-                     octx = octx->outer_context;
-                     if (octx->region_type == ORT_WORKSHARE
-                         && octx->combined_loop
-                         && splay_tree_lookup (octx->variables,
-                                               (splay_tree_key) decl) == NULL
-                         && !omp_check_private (octx, decl, false))
-                       {
-                         omp_add_variable (octx, decl,
-                                           GOVD_LASTPRIVATE | GOVD_SEEN);
-                         octx = octx->outer_context;
-                         if (octx
-                             && ((octx->region_type & ORT_COMBINED_TEAMS)
-                                 == ORT_COMBINED_TEAMS)
-                             && (splay_tree_lookup (octx->variables,
-                                                    (splay_tree_key) decl)
-                                 == NULL))
-                           {
-                             omp_add_variable (octx, decl,
-                                               GOVD_SHARED | GOVD_SEEN);
-                             octx = octx->outer_context;
-                           }
-                       }
-                     if (octx)
-                       omp_notice_variable (octx, decl, true);
-                   }
+                 continue;
                }
-             else if (outer_ctx->outer_context)
-               omp_notice_variable (outer_ctx->outer_context, decl, true);
+             if ((octx->region_type & ORT_TASK) != 0
+                 && octx->combined_loop
+                 && splay_tree_lookup (octx->variables,
+                                       (splay_tree_key) decl) == NULL)
+               {
+                 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
+                 continue;
+               }
+             if ((octx->region_type == ORT_WORKSHARE
+                  || octx->region_type == ORT_ACC)
+                 && octx->combined_loop
+                 && splay_tree_lookup (octx->variables,
+                                       (splay_tree_key) decl) == NULL
+                 && !omp_check_private (octx, decl, false))
+               {
+                 omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
+                 continue;
+               }
+             if (octx->region_type == ORT_COMBINED_TARGET
+                 && splay_tree_lookup (octx->variables,
+                                       (splay_tree_key) decl) == NULL)
+               {
+                 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
+                 octx = octx->outer_context;
+                 break;
+               }
+             break;
            }
+         if (octx && octx != outer_ctx)
+           omp_notice_variable (octx, decl, true);
          goto do_add;
        case OMP_CLAUSE_REDUCTION:
          if (OMP_CLAUSE_REDUCTION_TASK (c))
@@ -14643,7 +14616,7 @@ gimplify_expr (tree *expr_p, gimple_seq
                g = gimple_build_omp_section (body);
                break;
              case OMP_MASTER:
-               g = gimple_build_omp_master (body);
+               g = gimple_build_omp_master (body);
                break;
              case OMP_ORDERED:
                g = gimplify_omp_ordered (*expr_p, body);
--- gcc/c/c-parser.c.jj 2021-05-13 12:16:43.334627465 +0200
+++ gcc/c/c-parser.c    2021-05-18 16:53:24.795385017 +0200
@@ -18826,6 +18826,7 @@ c_parser_omp_master (location_t loc, c_p
          if (ret == NULL_TREE)
            return ret;
          ret = c_finish_omp_master (loc, block);
+         OMP_MASTER_COMBINED (ret) = 1;
          return ret;
        }
     }
@@ -19126,7 +19127,16 @@ c_parser_omp_parallel (location_t loc, c
                                        block);
          if (ret == NULL)
            return ret;
-         OMP_PARALLEL_COMBINED (stmt) = 1;
+         /* master doesn't have any clauses and during gimplification
+            isn't represented by a gimplification omp context, so for
+            #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
+            so that
+            #pragma omp parallel master
+            #pragma omp taskloop simd lastprivate (x)
+            isn't confused with
+            #pragma omp parallel master taskloop simd lastprivate (x)  */
+         if (OMP_MASTER_COMBINED (ret))
+           OMP_PARALLEL_COMBINED (stmt) = 1;
          return stmt;
        }
       else if (strcmp (p, "loop") == 0)
--- gcc/cp/parser.c.jj  2021-05-14 11:21:17.706310672 +0200
+++ gcc/cp/parser.c     2021-05-18 16:53:57.004031940 +0200
@@ -40922,7 +40922,9 @@ cp_parser_omp_master (cp_parser *parser,
          tree body = finish_omp_structured_block (sb);
          if (ret == NULL)
            return ret;
-         return c_finish_omp_master (loc, body);
+         ret = c_finish_omp_master (loc, body);
+         OMP_MASTER_COMBINED (ret) = 1;
+         return ret;
        }
     }
   if (!flag_openmp)  /* flag_openmp_simd  */
@@ -41206,7 +41208,16 @@ cp_parser_omp_parallel (cp_parser *parse
                                      block);
          if (ret == NULL_TREE)
            return ret;
-         OMP_PARALLEL_COMBINED (stmt) = 1;
+         /* master doesn't have any clauses and during gimplification
+            isn't represented by a gimplification omp context, so for
+            #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
+            so that
+            #pragma omp parallel master
+            #pragma omp taskloop simd lastprivate (x)
+            isn't confused with
+            #pragma omp parallel master taskloop simd lastprivate (x)  */
+         if (OMP_MASTER_COMBINED (ret))
+           OMP_PARALLEL_COMBINED (stmt) = 1;
          return stmt;
        }
       else if (strcmp (p, "loop") == 0)
--- gcc/testsuite/c-c++-common/gomp/pr99928-2.c.jj      2021-05-13 
16:53:31.062368335 +0200
+++ gcc/testsuite/c-c++-common/gomp/pr99928-2.c 2021-05-18 18:01:11.447774715 
+0200
@@ -92,38 +92,38 @@ bar (void)
     #pragma omp section
     l10 = 2;
   }
-  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l11" 
"gimple" { xfail *-*-* } } } */
-  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l11\\)" "gimple" { xfail *-*-* } } } */
+  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l11" 
"gimple" } } */
+  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l11\\)" "gimple" } } */
   /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l11\\)" 
"gimple" } } *//* FIXME: This should be on for instead.  */
   /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l11\\)" 
"gimple" } } *//* FIXME.  */
   #pragma omp target parallel for lastprivate (l11)
   for (int i = 0; i < 64; i++)
     l11 = i;
-  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l12" 
"gimple" { xfail *-*-* } } } */
-  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l12\\)" "gimple" { xfail *-*-* } } } */
+  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l12" 
"gimple" } } */
+  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l12\\)" "gimple" } } */
   /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l12\\)" 
"gimple" } } *//* FIXME: This should be on for instead.  */
   /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l12\\)" 
"gimple" } } *//* FIXME.  */
   /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l12\\)" 
"gimple" } } */
   #pragma omp target parallel for simd lastprivate (l12)
   for (int i = 0; i < 64; i++)
     l12 = i;
-  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j01" 
"gimple" { xfail *-*-* } } } */
-  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(j01\\)" "gimple" { xfail *-*-* } } } */
+  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j01" 
"gimple" } } */
+  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(j01\\)" "gimple" } } */
   /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j01\\)" 
"gimple" } } */
   /* { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(j01\\)" 
"gimple" } } *//* NOTE: This is implementation detail.  */
   /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(j01\\)" 
"gimple" } } *//* NOTE: This is implementation detail.  */
   #pragma omp target parallel loop lastprivate (j01)
   for (j01 = 0; j01 < 64; j01++)
     ;
-  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l13" 
"gimple" { xfail *-*-* } } } */
-  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l13\\)" "gimple" { xfail *-*-* } } } */
+  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l13" 
"gimple" } } */
+  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l13\\)" "gimple" } } */
   /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l13\\)" "gimple" 
} } */
   /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l13\\)" 
"gimple" } } */
   #pragma omp target teams distribute lastprivate (l13)
   for (int i = 0; i < 64; i++)
     l13 = i;
-  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l14" 
"gimple" { xfail *-*-* } } } */
-  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l14\\)" "gimple" { xfail *-*-* } } } */
+  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l14" 
"gimple" } } */
+  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l14\\)" "gimple" } } */
   /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l14\\)" "gimple" 
} } */
   /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l14\\)" 
"gimple" } } */
   /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l14\\)" 
"gimple" } } *//* FIXME: This should be on for instead.  */
@@ -131,8 +131,8 @@ bar (void)
   #pragma omp target teams distribute parallel for lastprivate (l14)
   for (int i = 0; i < 64; i++)
     l14 = i;
-  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l15" 
"gimple" { xfail *-*-* } } } */
-  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l15\\)" "gimple" { xfail *-*-* } } } */
+  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l15" 
"gimple" } } */
+  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l15\\)" "gimple" } } */
   /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l15\\)" "gimple" 
} } */
   /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l15\\)" 
"gimple" } } */
   /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l15\\)" 
"gimple" } } *//* FIXME: This should be on for instead.  */
@@ -141,16 +141,16 @@ bar (void)
   #pragma omp target teams distribute parallel for simd lastprivate (l15)
   for (int i = 0; i < 64; i++)
     l15 = i;
-  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l16" 
"gimple" { xfail *-*-* } } } */
-  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l16\\)" "gimple" { xfail *-*-* } } } */
+  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l16" 
"gimple" } } */
+  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l16\\)" "gimple" } } */
   /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(l16\\)" "gimple" 
} } */
   /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(l16\\)" 
"gimple" } } */
   /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l16\\)" 
"gimple" } } */
   #pragma omp target teams distribute simd lastprivate (l16)
   for (int i = 0; i < 64; i++)
     l16 = i;
-  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j02" 
"gimple" { xfail *-*-* } } } */
-  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(j02\\)" "gimple" { xfail *-*-* } } } */
+  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:j02" 
"gimple" } } */
+  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(j02\\)" "gimple" } } */
   /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(j02\\)" "gimple" 
} } */
   /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*lastprivate\\(j02\\)" 
"gimple" } } *//* NOTE: This is implementation detail.  */
   /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(j02\\)" 
"gimple" } } *//* NOTE: This is implementation detail.  */
@@ -159,8 +159,8 @@ bar (void)
   #pragma omp target teams loop lastprivate (j02)
   for (j02 = 0; j02 < 64; j02++)
     ;
-  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l17" 
"gimple" { xfail *-*-* } } } */
-  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l17\\)" "gimple" { xfail *-*-* } } } */
+  /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l17" 
"gimple" } } */
+  /* { dg-final { scan-tree-dump-not "omp 
target\[^\n\r]*firstprivate\\(l17\\)" "gimple" } } */
   /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l17\\)" 
"gimple" } } */
   #pragma omp target simd lastprivate (l17)
   for (int i = 0; i < 64; i++)
--- gcc/testsuite/c-c++-common/gomp/pr99928-12.c.jj     2021-05-18 
17:06:50.388542231 +0200
+++ gcc/testsuite/c-c++-common/gomp/pr99928-12.c        2021-05-18 
17:06:25.271818242 +0200
@@ -0,0 +1,23 @@
+/* PR middle-end/99928 */
+/* { dg-do compile } */
+
+int
+foo (void)
+{
+  int l = 0;
+  #pragma omp parallel master taskloop simd lastprivate (l) default(none)      
/* { dg-bogus "'l' not specified in enclosing 'parallel'" } */
+  for (int i = 0; i < 16; i++)
+    l = i;
+  return l;
+}
+
+int
+bar (void)
+{
+  int l = 0;
+  #pragma omp parallel master default(none)    /* { dg-message "enclosing 
'parallel'" } */
+  #pragma omp taskloop simd lastprivate (l)    /* { dg-error "'l' not 
specified in enclosing 'parallel'" } */
+  for (int i = 0; i < 16; i++)
+    l = i;
+  return l;
+}


        Jakub

Reply via email to