]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Add support for 2 argument num_teams clause
authorJakub Jelinek <jakub@redhat.com>
Thu, 11 Nov 2021 08:42:47 +0000 (09:42 +0100)
committerTobias Burnus <tobias@codesourcery.com>
Sun, 27 Feb 2022 20:43:42 +0000 (21:43 +0100)
In OpenMP 5.1, num_teams clause can accept either one expression as before,
but it in that case changed meaning, rather than create <= expression
teams it is now create == expression teams.  Or it accepts two expressions
separated by :, with the meaning that the first is low bound and second upper
bound on how many teams should be created.  The other ways to set number of
teams are upper bounds with lower bound of 1.

The following patch does parsing of this for C/C++.  For host teams, we
actually don't need to do anything further right now, we always create
(pretend to create) exactly the requested number of teams, so we can just
evaluate and throw away the lower bound for now.
For teams nested in target, we don't guarantee that though and further
work will be needed.
In particular, omplower now turns the teams part of:
struct S { S (); S (const S &); ~S (); int s; };
void bar (S &, S &);
int baz ();
_Pragma ("omp declare target to (baz)");

void
foo (void)
{
  S a, b;
  #pragma omp target private (a) map (b)
  {
    #pragma omp teams firstprivate (b) num_teams (baz ())
    {
      bar (a, b);
    }
  }
}
into:
  retval.0 = baz ();
  retval.1 = retval.0;
  {
    unsigned int retval.3;
    struct S * D.2549;
    struct S b;

    retval.3 = (unsigned int) retval.1;
    D.2549 = .omp_data_i->b;
    S::S (&b, D.2549);
    #pragma omp teams num_teams(retval.1) firstprivate(b) shared(a)
    __builtin_GOMP_teams (retval.3, 0);
    {
      bar (&a, &b);
    }
    S::~S (&b);
    #pragma omp return(nowait)
  }
IMHO we want a new API, say GOMP_teams3 which will take 3 arguments
instead of 2 (the lower and upper bounds from num_teams and thread_limit)
and will return a bool whether it should do the teams body or not.
And, we should add right before outermost {} above
while (__builtin_GOMP_teams3 ((unsigned) retval.1, (unsigned) retval.1, 0))
and remove the __builtin_GOMP_teams call.  The current function performs
exit equivalent (at least on NVPTX) which seems bad because that means
the destructors of e.g. private variables on target aren't invoked, and
at the current placement neither destructors of the already constructed
privatized variables in teams.
I'll do this next on the compiler side, but I'm afraid I'll need help
with the nvptx and amdgcn implementations.  E.g. for nvptx, we won't be
able to use %ctaid.x .  I think ideal would be to use a .shared
integer variable for the omp_get_team_num value, but I don't have any
experience with that, are .shared variables zero initialized by default,
or do they have random value at start?  PTX docs say they aren't initializable.

2021-11-11  Jakub Jelinek  <jakub@redhat.com>

gcc/
* tree.h (OMP_CLAUSE_NUM_TEAMS_EXPR): Rename to ...
(OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR): ... this.
(OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR): Define.
* tree.c (omp_clause_num_ops): Increase num ops for
OMP_CLAUSE_NUM_TEAMS to 2.
* tree-pretty-print.c (dump_omp_clause): Print optional lower bound
for OMP_CLAUSE_NUM_TEAMS.
* gimplify.c (gimplify_scan_omp_clauses): Gimplify
OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR if non-NULL.
(optimize_target_teams): Use OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR instead
of OMP_CLAUSE_NUM_TEAMS_EXPR.  Handle OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR.
* omp-low.c (lower_omp_teams): Use OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR
instead of OMP_CLAUSE_NUM_TEAMS_EXPR.
* omp-expand.c (expand_teams_call, get_target_arguments): Likewise.
gcc/c/
* c-parser.c (c_parser_omp_clause_num_teams): Parse optional
lower-bound and store it into OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR.
Use OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR instead of
OMP_CLAUSE_NUM_TEAMS_EXPR.
(c_parser_omp_target): For OMP_CLAUSE_NUM_TEAMS evaluate before
combined target teams even lower-bound expression.
gcc/cp/
* parser.c (cp_parser_omp_clause_num_teams): Parse optional
lower-bound and store it into OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR.
Use OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR instead of
OMP_CLAUSE_NUM_TEAMS_EXPR.
(cp_parser_omp_target): For OMP_CLAUSE_NUM_TEAMS evaluate before
combined target teams even lower-bound expression.
* semantics.c (finish_omp_clauses): Handle
OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR of OMP_CLAUSE_NUM_TEAMS clause.
* pt.c (tsubst_omp_clauses): Likewise.
(tsubst_expr): For OMP_CLAUSE_NUM_TEAMS evaluate before
combined target teams even lower-bound expression.
gcc/fortran/
* trans-openmp.c (gfc_trans_omp_clauses): Use
OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR instead of OMP_CLAUSE_NUM_TEAMS_EXPR.
gcc/testsuite/
* c-c++-common/gomp/clauses-1.c (bar): Supply lower-bound expression
to half of the num_teams clauses.
* c-c++-common/gomp/num-teams-1.c: New test.
* c-c++-common/gomp/num-teams-2.c: New test.
* g++.dg/gomp/attrs-1.C (bar): Supply lower-bound expression
to half of the num_teams clauses.
* g++.dg/gomp/attrs-2.C (bar): Likewise.
* g++.dg/gomp/num-teams-1.C: New test.
* g++.dg/gomp/num-teams-2.C: New test.
libgomp/
* testsuite/libgomp.c-c++-common/teams-1.c: New test.

(cherry picked from commit 48d7327f2aaf65e224f5f0793a65b950297f6c7f)

25 files changed:
gcc/ChangeLog.omp
gcc/c/ChangeLog.omp
gcc/c/c-parser.c
gcc/cp/ChangeLog.omp
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/fortran/ChangeLog.omp
gcc/fortran/trans-openmp.c
gcc/gimplify.c
gcc/omp-expand.c
gcc/omp-low.c
gcc/testsuite/ChangeLog.omp
gcc/testsuite/c-c++-common/gomp/clauses-1.c
gcc/testsuite/c-c++-common/gomp/num-teams-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/num-teams-2.c [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/attrs-1.C
gcc/testsuite/g++.dg/gomp/attrs-2.C
gcc/testsuite/g++.dg/gomp/num-teams-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/num-teams-2.C [new file with mode: 0644]
gcc/tree-pretty-print.c
gcc/tree.c
gcc/tree.h
libgomp/ChangeLog.omp
libgomp/testsuite/libgomp.c-c++-common/teams-1.c [new file with mode: 0644]

index 6ae003c760044ccaf39565216479831d2a74c404..33c521b387683d55f23a20cff87aa8898bd903d3 100644 (file)
@@ -1,3 +1,23 @@
+2022-02-27  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-11-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * tree.h (OMP_CLAUSE_NUM_TEAMS_EXPR): Rename to ...
+       (OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR): ... this.
+       (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR): Define.
+       * tree.c (omp_clause_num_ops): Increase num ops for
+       OMP_CLAUSE_NUM_TEAMS to 2.
+       * tree-pretty-print.c (dump_omp_clause): Print optional lower bound
+       for OMP_CLAUSE_NUM_TEAMS.
+       * gimplify.c (gimplify_scan_omp_clauses): Gimplify
+       OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR if non-NULL.
+       (optimize_target_teams): Use OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR instead
+       of OMP_CLAUSE_NUM_TEAMS_EXPR.  Handle OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR.
+       * omp-low.c (lower_omp_teams): Use OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR
+       instead of OMP_CLAUSE_NUM_TEAMS_EXPR.
+       * omp-expand.c (expand_teams_call, get_target_arguments): Likewise.
+
 2022-02-27  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index c1f9e860d16bbd938b16b3c5062b97015422f07a..919a4733299f3330ba9c4dd8e7588d11a48c20bc 100644 (file)
@@ -1,3 +1,15 @@
+2022-02-27  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-11-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-parser.c (c_parser_omp_clause_num_teams): Parse optional
+       lower-bound and store it into OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR.
+       Use OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR instead of
+       OMP_CLAUSE_NUM_TEAMS_EXPR.
+       (c_parser_omp_target): For OMP_CLAUSE_NUM_TEAMS evaluate before
+       combined target teams even lower-bound expression.
+
 2022-02-18  Kwok Cheung Yeung  <kcy@codesourcery.com>
 
        * c-parser.c (c_parser_omp_construct): Move handling of
index bb463c6d8afc2bfe755448488a67f3062e238755..466435a62b2f5dbad8cef7a94e2890f05251f479 100644 (file)
@@ -15211,7 +15211,10 @@ c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
 }
 
 /* OpenMP 4.0:
-   num_teams ( expression ) */
+   num_teams ( expression )
+
+   OpenMP 5.1:
+   num_teams ( expression : expression ) */
 
 static tree
 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
@@ -15220,34 +15223,68 @@ c_parser_omp_clause_num_teams (c_parser *parser, tree list)
   matching_parens parens;
   if (parens.require_open (parser))
     {
-      location_t expr_loc = c_parser_peek_token (parser)->location;
+      location_t upper_loc = c_parser_peek_token (parser)->location;
+      location_t lower_loc = UNKNOWN_LOCATION;
       c_expr expr = c_parser_expr_no_commas (parser, NULL);
-      expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
-      tree c, t = expr.value;
-      t = c_fully_fold (t, false, NULL);
+      expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
+      tree c, upper = expr.value, lower = NULL_TREE;
+      upper = c_fully_fold (upper, false, NULL);
+
+      if (c_parser_next_token_is (parser, CPP_COLON))
+       {
+         c_parser_consume_token (parser);
+         lower_loc = upper_loc;
+         lower = upper;
+         upper_loc = c_parser_peek_token (parser)->location;
+         expr = c_parser_expr_no_commas (parser, NULL);
+         expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
+         upper = expr.value;
+         upper = c_fully_fold (upper, false, NULL);
+       }
 
       parens.skip_until_found_close (parser);
 
-      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
+      if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
+         || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
        {
          c_parser_error (parser, "expected integer expression");
          return list;
        }
 
       /* Attempt to statically determine when the number isn't positive.  */
-      c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
-                          build_int_cst (TREE_TYPE (t), 0));
-      protected_set_expr_location (c, expr_loc);
+      c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
+                          build_int_cst (TREE_TYPE (upper), 0));
+      protected_set_expr_location (c, upper_loc);
       if (c == boolean_true_node)
        {
-         warning_at (expr_loc, 0, "%<num_teams%> value must be positive");
-         t = integer_one_node;
+         warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
+         upper = integer_one_node;
+       }
+      if (lower)
+       {
+         c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
+                              build_int_cst (TREE_TYPE (lower), 0));
+         protected_set_expr_location (c, lower_loc);
+         if (c == boolean_true_node)
+           {
+             warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
+             lower = NULL_TREE;
+           }
+         else if (TREE_CODE (lower) == INTEGER_CST
+                  && TREE_CODE (upper) == INTEGER_CST
+                  && tree_int_cst_lt (upper, lower))
+           {
+             warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
+                                       "than upper bound %qE", lower, upper);
+             lower = NULL_TREE;
+           }
        }
 
       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
 
       c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
-      OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
+      OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
+      OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
       OMP_CLAUSE_CHAIN (c) = list;
       list = c;
     }
@@ -21073,31 +21110,31 @@ c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
          if (ret == NULL_TREE)
            return false;
          if (ccode == OMP_TEAMS)
-           {
-             /* For combined target teams, ensure the num_teams and
-                thread_limit clause expressions are evaluated on the host,
-                before entering the target construct.  */
-             tree c;
-             for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
-                  c; c = OMP_CLAUSE_CHAIN (c))
-               if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
-                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
-                   && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
-                 {
-                   tree expr = OMP_CLAUSE_OPERAND (c, 0);
-                   tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
-                   expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
-                                  expr, NULL_TREE, NULL_TREE);
-                   add_stmt (expr);
-                   OMP_CLAUSE_OPERAND (c, 0) = expr;
-                   tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
-                                               OMP_CLAUSE_FIRSTPRIVATE);
-                   OMP_CLAUSE_DECL (tc) = tmp;
-                   OMP_CLAUSE_CHAIN (tc)
-                     = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
-                   cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
-                 }
-           }
+           /* For combined target teams, ensure the num_teams and
+              thread_limit clause expressions are evaluated on the host,
+              before entering the target construct.  */
+           for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+                c; c = OMP_CLAUSE_CHAIN (c))
+             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
+                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
+               for (int i = 0;
+                    i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
+                 if (OMP_CLAUSE_OPERAND (c, i)
+                     && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
+                   {
+                     tree expr = OMP_CLAUSE_OPERAND (c, i);
+                     tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
+                     expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
+                                    expr, NULL_TREE, NULL_TREE);
+                     add_stmt (expr);
+                     OMP_CLAUSE_OPERAND (c, i) = expr;
+                     tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+                                                 OMP_CLAUSE_FIRSTPRIVATE);
+                     OMP_CLAUSE_DECL (tc) = tmp;
+                     OMP_CLAUSE_CHAIN (tc)
+                       = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
+                     cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
+                   }
          tree stmt = make_node (OMP_TARGET);
          TREE_TYPE (stmt) = void_type_node;
          OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
index 03b72006567bb00ad4049fac0c1c44651e5d5a93..0b041e834f7242f89dcd5546ac9f8dcbccf83c51 100644 (file)
@@ -1,3 +1,20 @@
+2022-02-27  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-11-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * parser.c (cp_parser_omp_clause_num_teams): Parse optional
+       lower-bound and store it into OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR.
+       Use OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR instead of
+       OMP_CLAUSE_NUM_TEAMS_EXPR.
+       (cp_parser_omp_target): For OMP_CLAUSE_NUM_TEAMS evaluate before
+       combined target teams even lower-bound expression.
+       * semantics.c (finish_omp_clauses): Handle
+       OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR of OMP_CLAUSE_NUM_TEAMS clause.
+       * pt.c (tsubst_omp_clauses): Likewise.
+       (tsubst_expr): For OMP_CLAUSE_NUM_TEAMS evaluate before
+       combined target teams even lower-bound expression.
+
 2022-02-18  Kwok Cheung Yeung  <kcy@codesourcery.com>
 
        * parser.c (cp_parser_omp_construct): Move handling of
index c910aafd50841c6ead8c60ab617b0e8fc79733eb..368bcb39f233a477656fcebe8ffd7bd8323b5146 100644 (file)
@@ -38037,21 +38037,35 @@ cp_parser_omp_clause_orderedkind (cp_parser * /*parser*/,
 }
 
 /* OpenMP 4.0:
-   num_teams ( expression ) */
+   num_teams ( expression )
+
+   OpenMP 5.1:
+   num_teams ( expression : expression ) */
 
 static tree
 cp_parser_omp_clause_num_teams (cp_parser *parser, tree list,
                                location_t location)
 {
-  tree t, c;
+  tree upper, lower = NULL_TREE, c;
 
   matching_parens parens;
   if (!parens.require_open (parser))
     return list;
 
-  t = cp_parser_assignment_expression (parser);
+  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
+  parser->colon_corrects_to_scope_p = false;
+  upper = cp_parser_assignment_expression (parser);
+  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
 
-  if (t == error_mark_node
+  if (upper != error_mark_node
+      && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+    {
+      lower = upper;
+      cp_lexer_consume_token (parser->lexer);
+      upper = cp_parser_assignment_expression (parser);
+    }
+
+  if (upper == error_mark_node
       || !parens.require_close (parser))
     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                           /*or_comma=*/false,
@@ -38061,7 +38075,8 @@ cp_parser_omp_clause_num_teams (cp_parser *parser, tree list,
                             "num_teams", location);
 
   c = build_omp_clause (location, OMP_CLAUSE_NUM_TEAMS);
-  OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
+  OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
+  OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
   OMP_CLAUSE_CHAIN (c) = list;
 
   return c;
@@ -43878,32 +43893,33 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
          if (ret == NULL_TREE)
            return false;
          if (ccode == OMP_TEAMS && !processing_template_decl)
-           {
-             /* For combined target teams, ensure the num_teams and
-                thread_limit clause expressions are evaluated on the host,
-                before entering the target construct.  */
-             tree c;
-             for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
-                  c; c = OMP_CLAUSE_CHAIN (c))
-               if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
-                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
-                   && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
-                 {
-                   tree expr = OMP_CLAUSE_OPERAND (c, 0);
-                   expr = force_target_expr (TREE_TYPE (expr), expr, tf_none);
-                   if (expr == error_mark_node)
-                     continue;
-                   tree tmp = TARGET_EXPR_SLOT (expr);
-                   add_stmt (expr);
-                   OMP_CLAUSE_OPERAND (c, 0) = expr;
-                   tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
-                                               OMP_CLAUSE_FIRSTPRIVATE);
-                   OMP_CLAUSE_DECL (tc) = tmp;
-                   OMP_CLAUSE_CHAIN (tc)
-                     = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
-                   cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
-                 }
-           }
+           /* For combined target teams, ensure the num_teams and
+              thread_limit clause expressions are evaluated on the host,
+              before entering the target construct.  */
+           for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+                c; c = OMP_CLAUSE_CHAIN (c))
+             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
+                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
+               for (int i = 0;
+                    i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
+                 if (OMP_CLAUSE_OPERAND (c, i)
+                     && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
+                   {
+                     tree expr = OMP_CLAUSE_OPERAND (c, i);
+                     expr = force_target_expr (TREE_TYPE (expr), expr,
+                                               tf_none);
+                     if (expr == error_mark_node)
+                       continue;
+                     tree tmp = TARGET_EXPR_SLOT (expr);
+                     add_stmt (expr);
+                     OMP_CLAUSE_OPERAND (c, i) = expr;
+                     tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+                                                 OMP_CLAUSE_FIRSTPRIVATE);
+                     OMP_CLAUSE_DECL (tc) = tmp;
+                     OMP_CLAUSE_CHAIN (tc)
+                       = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
+                     cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
+                   }
          c_omp_adjust_map_clauses (cclauses[C_OMP_CLAUSE_SPLIT_TARGET], true);
          finish_omp_target (pragma_tok->location,
                             cclauses[C_OMP_CLAUSE_SPLIT_TARGET], body, true);
index d33cd3d9473ec95cac22b9673f8d2a399689049a..6e40364a4e53c36270119050b0404d1888d61030 100644 (file)
@@ -17460,6 +17460,13 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
            = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
                                      in_decl, iterator_cache);
          break;
+       case OMP_CLAUSE_NUM_TEAMS:
+         if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (oc))
+           OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (nc)
+             = tsubst_expr (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (oc), args,
+                            complain, in_decl,
+                            /*integral_constant_expression_p=*/false);
+         /* FALLTHRU */
        case OMP_CLAUSE_TILE:
        case OMP_CLAUSE_IF:
        case OMP_CLAUSE_NUM_THREADS:
@@ -17468,7 +17475,6 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
        case OMP_CLAUSE_FINAL:
        case OMP_CLAUSE_DEVICE:
        case OMP_CLAUSE_DIST_SCHEDULE:
-       case OMP_CLAUSE_NUM_TEAMS:
        case OMP_CLAUSE_THREAD_LIMIT:
        case OMP_CLAUSE_SAFELEN:
        case OMP_CLAUSE_SIMDLEN:
@@ -18969,31 +18975,32 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
        {
          tree teams = cp_walk_tree (&stmt, tsubst_find_omp_teams, NULL, NULL);
          if (teams)
-           {
-             /* For combined target teams, ensure the num_teams and
-                thread_limit clause expressions are evaluated on the host,
-                before entering the target construct.  */
-             tree c;
-             for (c = OMP_TEAMS_CLAUSES (teams);
-                  c; c = OMP_CLAUSE_CHAIN (c))
-               if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
-                    || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
-                   && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
-                 {
-                   tree expr = OMP_CLAUSE_OPERAND (c, 0);
-                   expr = force_target_expr (TREE_TYPE (expr), expr, tf_none);
-                   if (expr == error_mark_node)
-                     continue;
-                   tmp = TARGET_EXPR_SLOT (expr);
-                   add_stmt (expr);
-                   OMP_CLAUSE_OPERAND (c, 0) = expr;
-                   tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
-                                               OMP_CLAUSE_FIRSTPRIVATE);
-                   OMP_CLAUSE_DECL (tc) = tmp;
-                   OMP_CLAUSE_CHAIN (tc) = OMP_TARGET_CLAUSES (t);
-                   OMP_TARGET_CLAUSES (t) = tc;
-                 }
-           }
+           /* For combined target teams, ensure the num_teams and
+              thread_limit clause expressions are evaluated on the host,
+              before entering the target construct.  */
+           for (tree c = OMP_TEAMS_CLAUSES (teams);
+                c; c = OMP_CLAUSE_CHAIN (c))
+             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
+                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
+               for (int i = 0;
+                    i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
+                 if (OMP_CLAUSE_OPERAND (c, i)
+                     && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
+                   {
+                     tree expr = OMP_CLAUSE_OPERAND (c, i);
+                     expr = force_target_expr (TREE_TYPE (expr), expr,
+                                               tf_none);
+                     if (expr == error_mark_node)
+                       continue;
+                     tmp = TARGET_EXPR_SLOT (expr);
+                     add_stmt (expr);
+                     OMP_CLAUSE_OPERAND (c, i) = expr;
+                     tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+                                                 OMP_CLAUSE_FIRSTPRIVATE);
+                     OMP_CLAUSE_DECL (tc) = tmp;
+                     OMP_CLAUSE_CHAIN (tc) = OMP_TARGET_CLAUSES (t);
+                     OMP_TARGET_CLAUSES (t) = tc;
+                   }
        }
       add_stmt (t);
       break;
index 87f996fec1f1acb03986ae98d0bddaf6a8619990..a066873b7f0879c67437fdf8e311a99c76bbf369 100644 (file)
@@ -7285,6 +7285,53 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                }
              OMP_CLAUSE_OPERAND (c, 0) = t;
            }
+         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
+             && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
+             && !remove)
+           {
+             t = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
+             if (t == error_mark_node)
+               remove = true;
+             else if (!type_dependent_expression_p (t)
+                      && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+               {
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "%qs expression must be integral",
+                           omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+                 remove = true;
+               }
+             else
+               {
+                 t = mark_rvalue_use (t);
+                 if (!processing_template_decl)
+                   {
+                     t = maybe_constant_value (t);
+                     if (TREE_CODE (t) == INTEGER_CST
+                         && tree_int_cst_sgn (t) != 1)
+                       {
+                         warning_at (OMP_CLAUSE_LOCATION (c), 0,
+                                     "%qs value must be positive",
+                                     omp_clause_code_name
+                                     [OMP_CLAUSE_CODE (c)]);
+                         t = NULL_TREE;
+                       }
+                     else
+                       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+                     tree upper = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c);
+                     if (t
+                         && TREE_CODE (t) == INTEGER_CST
+                         && TREE_CODE (upper) == INTEGER_CST
+                         && tree_int_cst_lt (upper, t))
+                       {
+                         warning_at (OMP_CLAUSE_LOCATION (c), 0,
+                                     "%<num_teams%> lower bound %qE bigger "
+                                     "than upper bound %qE", t, upper);
+                         t = NULL_TREE;
+                       }
+                   }
+                 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = t;
+               }
+           }
          break;
 
        case OMP_CLAUSE_SCHEDULE:
index e76884dbc0c88a3411faf466a0ebe1e4727ed1a4..5ea9585544988aa095dba0599198eb9cd59bcafc 100644 (file)
@@ -1,3 +1,11 @@
+2022-02-27  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-11-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * trans-openmp.c (gfc_trans_omp_clauses): Use
+       OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR instead of OMP_CLAUSE_NUM_TEAMS_EXPR.
+
 2022-02-11  Kwok Cheung Yeung  <kcy@codesourcery.com>
 
        * gfortran.h (is_omp_declarative_stmt): New.
index 3bb4feb8fa55265a18919424871dcc03d30f2c01..4dd53f0bb1256c919539899523c3af3ade40a2f9 100644 (file)
@@ -3958,7 +3958,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
       gfc_add_block_to_block (block, &se.post);
 
       c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_NUM_TEAMS);
-      OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
+      OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams;
       omp_clauses = gfc_trans_add_clause (c, omp_clauses);
     }
 
index b0226e98d02c16116ce4db7a77aeb929930add31..2af3c10e76b9bee70b01f1ec723e4813878a49ce 100644 (file)
@@ -10844,9 +10844,24 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
            = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
          /* Fall through.  */
 
+       case OMP_CLAUSE_NUM_TEAMS:
+         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
+             && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
+             && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
+           {
+             if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
+               {
+                 remove = true;
+                 break;
+               }
+             OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
+               = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
+                                          pre_p, NULL, true);
+           }
+         /* Fall through.  */
+
        case OMP_CLAUSE_SCHEDULE:
        case OMP_CLAUSE_NUM_THREADS:
-       case OMP_CLAUSE_NUM_TEAMS:
        case OMP_CLAUSE_THREAD_LIMIT:
        case OMP_CLAUSE_DIST_SCHEDULE:
        case OMP_CLAUSE_DEVICE:
@@ -14358,7 +14373,8 @@ optimize_target_teams (tree target, gimple_seq *pre_p)
 {
   tree body = OMP_BODY (target);
   tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
-  tree num_teams = integer_zero_node;
+  tree num_teams_lower = NULL_TREE;
+  tree num_teams_upper = integer_zero_node;
   tree thread_limit = integer_zero_node;
   location_t num_teams_loc = EXPR_LOCATION (target);
   location_t thread_limit_loc = EXPR_LOCATION (target);
@@ -14366,14 +14382,42 @@ optimize_target_teams (tree target, gimple_seq *pre_p)
   struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
 
   if (teams == NULL_TREE)
-    num_teams = integer_one_node;
+    num_teams_upper = integer_one_node;
   else
     for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
       {
        if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
          {
-           p = &num_teams;
+           p = &num_teams_upper;
            num_teams_loc = OMP_CLAUSE_LOCATION (c);
+           if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
+             {
+               expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
+               if (TREE_CODE (expr) == INTEGER_CST)
+                 num_teams_lower = expr;
+               else if (walk_tree (&expr, computable_teams_clause,
+                                   NULL, NULL))
+                 num_teams_lower = integer_minus_one_node;
+               else
+                 {
+                   num_teams_lower = expr;
+                   gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
+                   if (gimplify_expr (&num_teams_lower, pre_p, NULL,
+                                      is_gimple_val, fb_rvalue, false)
+                       == GS_ERROR)
+                     {
+                       gimplify_omp_ctxp = target_ctx;
+                       num_teams_lower = integer_minus_one_node;
+                     }
+                   else
+                     {
+                       gimplify_omp_ctxp = target_ctx;
+                       if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
+                         OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
+                           = num_teams_lower;
+                     }
+                 }
+             }
          }
        else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
          {
@@ -14411,7 +14455,8 @@ optimize_target_teams (tree target, gimple_seq *pre_p)
   OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   OMP_TARGET_CLAUSES (target) = c;
   c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
-  OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
+  OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
+  OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
   OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   OMP_TARGET_CLAUSES (target) = c;
 }
index 2f9f4cd1d4853d487fc36ad119c6330de5c00ee5..5da8f2034c1fc6608b32e03482d7afd651e9a8a0 100644 (file)
@@ -941,7 +941,7 @@ expand_teams_call (basic_block bb, gomp_teams *entry_stmt)
     num_teams = build_int_cst (unsigned_type_node, 0);
   else
     {
-      num_teams = OMP_CLAUSE_NUM_TEAMS_EXPR (num_teams);
+      num_teams = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (num_teams);
       num_teams = fold_convert (unsigned_type_node, num_teams);
     }
   tree thread_limit = omp_find_clause (clauses, OMP_CLAUSE_THREAD_LIMIT);
@@ -9706,7 +9706,7 @@ get_target_arguments (gimple_stmt_iterator *gsi, gomp_target *tgt_stmt)
   tree clauses = gimple_omp_target_clauses (tgt_stmt);
   tree t, c = omp_find_clause (clauses, OMP_CLAUSE_NUM_TEAMS);
   if (c)
-    t = OMP_CLAUSE_NUM_TEAMS_EXPR (c);
+    t = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c);
   else
     t = integer_minus_one_node;
   push_target_argument_according_to_value (gsi, GOMP_TARGET_ARG_DEVICE_ALL,
index 8f748a442c8fa13064ad0d2562c50379356f826e..5a211e6555f2449c8f627ec3df41cec5c8ffb4d7 100644 (file)
@@ -14628,7 +14628,7 @@ lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
     num_teams = build_int_cst (unsigned_type_node, 0);
   else
     {
-      num_teams = OMP_CLAUSE_NUM_TEAMS_EXPR (num_teams);
+      num_teams = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (num_teams);
       num_teams = fold_convert (unsigned_type_node, num_teams);
       gimplify_expr (&num_teams, &bind_body, NULL, is_gimple_val, fb_rvalue);
     }
index 02ab20e8faa07b131f8421dedf09fc2404156de1..6fb3ebea05a4fccc41450ae0d09bfa18b004a752 100644 (file)
@@ -1,3 +1,18 @@
+2022-02-27  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-11-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-c++-common/gomp/clauses-1.c (bar): Supply lower-bound expression
+       to half of the num_teams clauses.
+       * c-c++-common/gomp/num-teams-1.c: New test.
+       * c-c++-common/gomp/num-teams-2.c: New test.
+       * g++.dg/gomp/attrs-1.C (bar): Supply lower-bound expression
+       to half of the num_teams clauses.
+       * g++.dg/gomp/attrs-2.C (bar): Likewise.
+       * g++.dg/gomp/num-teams-1.C: New test.
+       * g++.dg/gomp/num-teams-2.C: New test.
+
 2022-02-27  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index 742132f202eb873f962e0f605428dcec77dc0b8e..3ff49e0a29829ddab278804ccde7e3a972f8c637 100644 (file)
@@ -164,7 +164,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ll++;
   #pragma omp target teams \
     device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
-    shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0]) \
+    shared(s) default(shared) reduction(+:r) num_teams(nte - 1:nte) thread_limit(tl) nowait depend(inout: dd[0]) \
     allocate (omp_default_mem_alloc:f) in_reduction(+:r2)
     ;
   #pragma omp target teams distribute \
@@ -175,7 +175,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ;
   #pragma omp target teams distribute parallel for \
     device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
-    shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl) \
     collapse(1) dist_schedule(static, 16) \
     if (parallel: i2) num_threads (nth) proc_bind(spread) \
     lastprivate (l) schedule(static, 4) nowait depend(inout: dd[0]) order(concurrent) \
@@ -194,7 +194,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ll++;
   #pragma omp target teams distribute simd \
     device(d) map (tofrom: m) if (i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
-    shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl) \
     collapse(1) dist_schedule(static, 16) order(concurrent) \
     safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) \
     allocate (omp_default_mem_alloc:f) in_reduction(+:r2)
@@ -236,7 +236,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ;
   #pragma omp target
   #pragma omp teams distribute parallel for \
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl) \
     collapse(1) dist_schedule(static, 16) \
     if (parallel: i2) num_threads (nth) proc_bind(spread) \
     lastprivate (l) schedule(static, 4) order(concurrent) allocate (omp_default_mem_alloc: f)
@@ -254,7 +254,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ll++;
   #pragma omp target
   #pragma omp teams distribute simd \
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl) \
     collapse(1) dist_schedule(static, 16) order(concurrent) \
     safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm) \
     allocate (omp_default_mem_alloc: f)
@@ -268,7 +268,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp teams distribute parallel for \
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl) \
     collapse(1) dist_schedule(static, 16) order(concurrent) \
     if (parallel: i2) num_threads (nth) proc_bind(spread) \
     lastprivate (l) schedule(static, 4) allocate (f)
@@ -284,7 +284,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp teams distribute parallel for simd \
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl) \
     collapse(1) dist_schedule(static, 16) \
     if (parallel: i2) num_threads (nth) proc_bind(spread) \
     lastprivate (l) schedule(static, 4) order(concurrent) \
@@ -417,7 +417,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (l = 0; l < 64; l++)
     ll++;
   #pragma omp teams loop \
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl) \
     collapse(1) lastprivate (l) bind(teams) allocate (f)
   for (l = 0; l < 64; ++l)
     ;
@@ -442,7 +442,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ;
   #pragma omp target teams loop \
     device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
-    shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0]) \
+    shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl) nowait depend(inout: dd[0]) \
     lastprivate (l) bind(teams) collapse(1) \
     allocate (omp_default_mem_alloc: f) in_reduction(+:r2)
   for (l = 0; l < 64; ++l)
diff --git a/gcc/testsuite/c-c++-common/gomp/num-teams-1.c b/gcc/testsuite/c-c++-common/gomp/num-teams-1.c
new file mode 100644 (file)
index 0000000..50cad85
--- /dev/null
@@ -0,0 +1,48 @@
+int fn (int);
+
+void
+foo (void)
+{
+  #pragma omp teams num_teams (4 : 6)
+  ;
+  #pragma omp teams num_teams (7)
+  ;
+}
+
+void
+bar (void)
+{
+  #pragma omp target teams num_teams (5 : 19)
+  ;
+  #pragma omp target teams num_teams (21)
+  ;
+}
+
+void
+baz (void)
+{
+  #pragma omp teams num_teams (fn (1) : fn (2))
+  ;
+  #pragma omp teams num_teams (fn (3))
+  ;
+}
+
+void
+qux (void)
+{
+  #pragma omp target teams num_teams (fn (4) : fn (5))
+  ;
+  #pragma omp target teams num_teams (fn (6))
+  ;
+}
+
+void
+corge (void)
+{
+  #pragma omp target
+  #pragma omp teams num_teams (fn (7) : fn (8))
+  ;
+  #pragma omp target
+  #pragma omp teams num_teams (fn (9))
+  ;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/num-teams-2.c b/gcc/testsuite/c-c++-common/gomp/num-teams-2.c
new file mode 100644 (file)
index 0000000..242b994
--- /dev/null
@@ -0,0 +1,27 @@
+int fn (int);
+
+void
+foo (int i)
+{
+  #pragma omp teams num_teams (6 : 4)          /* { dg-warning "'num_teams' lower bound '6' bigger than upper bound '4'" } */
+  ;
+  #pragma omp teams num_teams (-7)             /* { dg-warning "'num_teams' value must be positive" } */
+  ;
+  #pragma omp teams num_teams (i : -7)         /* { dg-warning "'num_teams' value must be positive" } */
+  ;
+  #pragma omp teams num_teams (-7 : 8)         /* { dg-warning "'num_teams' value must be positive" } */
+  ;
+}
+
+void
+bar (int i)
+{
+  #pragma omp target teams num_teams (6 : 4)   /* { dg-warning "'num_teams' lower bound '6' bigger than upper bound '4'" } */
+  ;
+  #pragma omp target teams num_teams (-7)      /* { dg-warning "'num_teams' value must be positive" } */
+  ;
+  #pragma omp target teams num_teams (i : -7)  /* { dg-warning "'num_teams' value must be positive" } */
+  ;
+  #pragma omp target teams num_teams (-7 : 8)  /* { dg-warning "'num_teams' value must be positive" } */
+  ;
+}
index 2a5f2cf63234415b513c12d4839074311ba9db37..319ad3241de7dc99e8f4fd5fe76598ebd14889ed 100644 (file)
@@ -211,7 +211,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ll++;
   [[omp::sequence (directive (target teams
     device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
-    shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0])
+    shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl) nowait depend(inout: dd[0])
     allocate (omp_default_mem_alloc:f) in_reduction(+:r2)))]]
     ;
   [[omp::sequence (directive (target
@@ -226,7 +226,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ;
   [[omp::directive (target teams distribute parallel for
     device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
-    shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+    shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl)
     collapse(1) dist_schedule(static, 16)
     if (parallel: i2) num_threads (nth) proc_bind(spread)
     lastprivate (l) schedule(static, 4) nowait depend(inout: dd[0]) order(concurrent)
@@ -245,7 +245,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ll++;
   [[omp::directive (target teams distribute simd
     device(d) map (tofrom: m) if (i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
-    shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+    shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl)
     collapse(1) dist_schedule(static, 16) order(concurrent)
     safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm)
     allocate (omp_default_mem_alloc:f) in_reduction(+:r2))]]
@@ -309,7 +309,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ;
   [[omp::directive (teams
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl)
     allocate (omp_default_mem_alloc: f))]]
     ;
   [[omp::sequence (omp::directive (target),
@@ -322,7 +322,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ll++;
   [[omp::sequence (directive (target),
     directive (teams distribute parallel for simd
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl)
     collapse(1) dist_schedule(static, 16)
     if (parallel: i2) num_threads (nth) proc_bind(spread)
     lastprivate (l) schedule(static, 4) order(concurrent)
@@ -339,7 +339,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   [[omp::directive (teams distribute parallel for
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl)
     collapse(1) dist_schedule(static, 16)
     if (parallel: i2) num_threads (nth) proc_bind(spread)
     lastprivate (l) schedule(static, 4) copyin(t) allocate (f))]]
@@ -353,7 +353,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   [[omp::directive (teams distribute parallel for simd
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl)
     collapse(1) dist_schedule(static, 16)
     if (parallel: i2) num_threads (nth) proc_bind(spread)
     lastprivate (l) schedule(static, 4)
@@ -371,7 +371,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   [[omp::directive (teams distribute simd
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte-1:nte) thread_limit(tl)
     collapse(1) dist_schedule(static, 16) order(concurrent)
     safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm) allocate(f))]]
   for (int i = 0; i < 64; i++)
@@ -507,7 +507,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (l = 0; l < 64; ++l)
     ;
   [[omp::directive (teams loop
-    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl)
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte - 1:nte) thread_limit(tl)
     collapse(1) lastprivate (l) order(concurrent) allocate (f))]]
   for (l = 0; l < 64; ++l)
     ;
@@ -534,7 +534,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ;
   [[omp::directive (target teams loop
     device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp)
-    shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0])
+    shared(s) default(shared) reduction(+:r) num_teams(nte - 1 : nte) thread_limit(tl) nowait depend(inout: dd[0])
     lastprivate (l) order(concurrent) collapse(1)
     allocate (omp_default_mem_alloc: f) in_reduction(+:r2))]]
   for (l = 0; l < 64; ++l)
index c00be7f1db71e46bac71cfb2b642e9190dbdd3d8..955b2dd04c7b8805dcc4e694aef53a727cec97ef 100644 (file)
@@ -220,7 +220,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ;
   [[omp::sequence (omp::directive (target teams distribute,
     device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
-    shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),order(concurrent),
+    shared(s),default(shared),reduction(+:r),num_teams(nte-1:nte),thread_limit(tl),order(concurrent),
     collapse(1),dist_schedule(static, 16),nowait depend(inout: dd[0]),allocate (omp_default_mem_alloc:f),in_reduction(+:r2)))]]
   for (int i = 0; i < 64; i++)
     ;
@@ -235,7 +235,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ll++;
   [[omp::directive (target teams distribute parallel for simd,
     device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
-    shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+    shared(s),default(shared),reduction(+:r),num_teams(2:nte),thread_limit(tl),
     collapse(1),dist_schedule(static, 16),
     if (parallel: i2),num_threads (nth),proc_bind(spread),
     lastprivate (l),schedule(static, 4),order(concurrent),
@@ -304,7 +304,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   [[omp::directive (taskwait)]];
   [[omp::sequence (directive (target, nowait,depend(inout: dd[0]),in_reduction(+:r2)),
     directive (teams distribute,
-    private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+    private(p),firstprivate(f),shared(s),default(shared),reduction(+:r),num_teams(nte - 1 : nte),thread_limit(tl),
     collapse(1),dist_schedule(static, 16),allocate (omp_default_mem_alloc: f),order(concurrent)))]]
   for (int i = 0; i < 64; i++)
     ;
@@ -314,7 +314,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ;
   [[omp::sequence (omp::directive (target),
     omp::directive (teams distribute parallel for,
-    private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+    private(p),firstprivate(f),shared(s),default(shared),reduction(+:r),num_teams(16:nte),thread_limit(tl),
     collapse(1),dist_schedule(static, 16),
     if (parallel: i2),num_threads (nth),proc_bind(spread),
     lastprivate (l),schedule(static, 4),order(concurrent),allocate (omp_default_mem_alloc: f)))]]
@@ -332,7 +332,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ll++;
   [[omp::sequence (directive (target),
     directive (teams distribute simd,
-    private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+    private(p),firstprivate(f),shared(s),default(shared),reduction(+:r),num_teams(nte-1:nte),thread_limit(tl),
     collapse(1),dist_schedule(static, 16),order(concurrent),
     safelen(8),simdlen(4),aligned(q: 32),if(i3),nontemporal(ntm),
     allocate (omp_default_mem_alloc: f)))]]
@@ -346,7 +346,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   [[omp::directive (teams distribute parallel for,
-    private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+    private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte-1:nte),thread_limit(tl),
     collapse(1),dist_schedule(static, 16),order(concurrent),
     if (parallel: i2),num_threads (nth),proc_bind(spread),
     lastprivate (l),schedule(static, 4),allocate (f))]]
@@ -362,7 +362,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   [[omp::directive (teams distribute parallel for simd,
-    private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+    private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte-1:nte),thread_limit(tl),
     collapse(1),dist_schedule(static, 16),
     if (parallel: i2),num_threads (nth),proc_bind(spread),
     lastprivate (l),schedule(static, 4),order(concurrent),
@@ -502,7 +502,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
   for (l = 0; l < 64; l++)
     ll++;
   [[omp::directive (teams loop,
-    private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),
+    private(p),firstprivate (f),shared(s),default(shared),reduction(+:r),num_teams(nte-1:nte),thread_limit(tl),
     collapse(1),lastprivate (l),bind(teams),allocate (f))]]
   for (l = 0; l < 64; ++l)
     ;
@@ -527,7 +527,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
     ;
   [[omp::directive (target teams loop,
     device(d),map (tofrom: m),if (target: i1),private (p),firstprivate (f),defaultmap(tofrom: scalar),is_device_ptr (idp),
-    shared(s),default(shared),reduction(+:r),num_teams(nte),thread_limit(tl),nowait,depend(inout: dd[0]),
+    shared(s),default(shared),reduction(+:r),num_teams(nte-1:nte),thread_limit(tl),nowait,depend(inout: dd[0]),
     lastprivate (l),bind(teams),collapse(1),
     allocate (omp_default_mem_alloc: f),in_reduction(+:r2))]]
   for (l = 0; l < 64; ++l)
diff --git a/gcc/testsuite/g++.dg/gomp/num-teams-1.C b/gcc/testsuite/g++.dg/gomp/num-teams-1.C
new file mode 100644 (file)
index 0000000..5b36ffb
--- /dev/null
@@ -0,0 +1,122 @@
+int fn1 (int);
+template <typename T>
+T fn2 (T);
+
+template <int N>
+void
+f1 ()
+{
+  #pragma omp teams num_teams (4 : 6)
+  ;
+  #pragma omp teams num_teams (7)
+  ;
+}
+
+template <int N>
+void
+f2 ()
+{
+  #pragma omp target teams num_teams (5 : 19)
+  ;
+  #pragma omp target teams num_teams (21)
+  ;
+}
+
+template <int N>
+void
+f3 ()
+{
+  #pragma omp teams num_teams (fn1 (1) : fn1 (2))
+  ;
+  #pragma omp teams num_teams (fn1 (3))
+  ;
+}
+
+template <int N>
+void
+f4 ()
+{
+  #pragma omp target teams num_teams (fn1 (4) : fn1 (5))
+  ;
+  #pragma omp target teams num_teams (fn1 (6))
+  ;
+}
+
+template <int N>
+void
+f5 ()
+{
+  #pragma omp target
+  #pragma omp teams num_teams (fn1 (7) : fn1 (8))
+  ;
+  #pragma omp target
+  #pragma omp teams num_teams (fn1 (9))
+  ;
+}
+
+template <typename T, T N4, T N6, T N7>
+void
+f1 ()
+{
+  #pragma omp teams num_teams (N4 : N6)
+  ;
+  #pragma omp teams num_teams (N7)
+  ;
+}
+
+template <typename T, T N5, T N19, T N21>
+void
+f2 ()
+{
+  #pragma omp target teams num_teams (N5 : N19)
+  ;
+  #pragma omp target teams num_teams (N21)
+  ;
+}
+
+template <typename T, T N1, T N2, T N3>
+void
+f3 ()
+{
+  #pragma omp teams num_teams (fn2 (N1) : fn2 (N2))
+  ;
+  #pragma omp teams num_teams (fn2 (N3))
+  ;
+}
+
+template <typename T, T N4, T N5, T N6>
+void
+f4 ()
+{
+  #pragma omp target teams num_teams (fn2 (N4) : fn2 (N5))
+  ;
+  #pragma omp target teams num_teams (fn2 (N6))
+  ;
+}
+
+template <typename T, T N7, T N8, T N9>
+void
+f5 ()
+{
+  #pragma omp target
+  #pragma omp teams num_teams (fn2 (N7) : fn2 (N8))
+  ;
+  #pragma omp target
+  #pragma omp teams num_teams (fn2 (N9))
+  ;
+}
+
+void
+test ()
+{
+  f1<0> ();
+  f2<0> ();
+  f3<0> ();
+  f4<0> ();
+  f5<0> ();
+  f1<int, 4, 6, 7> ();
+  f2<int, 5, 19, 21> ();
+  f3<int, 1, 2, 3> ();
+  f4<int, 4, 5, 6> ();
+  f5<int, 7, 8, 9> ();
+}
diff --git a/gcc/testsuite/g++.dg/gomp/num-teams-2.C b/gcc/testsuite/g++.dg/gomp/num-teams-2.C
new file mode 100644 (file)
index 0000000..8b8933c
--- /dev/null
@@ -0,0 +1,64 @@
+template <int N>
+void
+foo (int i)
+{
+  #pragma omp teams num_teams (6 : 4)          // { dg-warning "'num_teams' lower bound '6' bigger than upper bound '4'" }
+  ;
+  #pragma omp teams num_teams (-7)             // { dg-warning "'num_teams' value must be positive" }
+  ;
+  #pragma omp teams num_teams (i : -7)         // { dg-warning "'num_teams' value must be positive" }
+  ;
+  #pragma omp teams num_teams (-7 : 8)         // { dg-warning "'num_teams' value must be positive" }
+  ;
+}
+
+template <int N>
+void
+bar (int i)
+{
+  #pragma omp target teams num_teams (6 : 4)   // { dg-warning "'num_teams' lower bound '6' bigger than upper bound '4'" }
+  ;
+  #pragma omp target teams num_teams (-7)      // { dg-warning "'num_teams' value must be positive" }
+  ;
+  #pragma omp target teams num_teams (i : -7)  // { dg-warning "'num_teams' value must be positive" }
+  ;
+  #pragma omp target teams num_teams (-7 : 8)  // { dg-warning "'num_teams' value must be positive" }
+  ;
+}
+
+template <typename T, T NM7, T N4, T N6, T N8>
+void
+baz (T i)
+{
+  #pragma omp teams num_teams (N6 : N4)                // { dg-warning "'num_teams' lower bound '6' bigger than upper bound '4'" }
+  ;
+  #pragma omp teams num_teams (NM7)            // { dg-warning "'num_teams' value must be positive" }
+  ;
+  #pragma omp teams num_teams (i : NM7)                // { dg-warning "'num_teams' value must be positive" }
+  ;
+  #pragma omp teams num_teams (NM7 : N8)       // { dg-warning "'num_teams' value must be positive" }
+  ;
+}
+
+template <typename T, T NM7, T N4, T N6, T N8>
+void
+qux (T i)
+{
+  #pragma omp target teams num_teams (N6 : N4) // { dg-warning "'num_teams' lower bound '6' bigger than upper bound '4'" }
+  ;
+  #pragma omp target teams num_teams (NM7)     // { dg-warning "'num_teams' value must be positive" }
+  ;
+  #pragma omp target teams num_teams (i : NM7) // { dg-warning "'num_teams' value must be positive" }
+  ;
+  #pragma omp target teams num_teams (NM7 : N8)        // { dg-warning "'num_teams' value must be positive" }
+  ;
+}
+
+void
+test ()
+{
+  foo<0> (5);
+  bar<0> (5);
+  baz<int, -7, 4, 6, 8> (5);
+  qux<int, -7, 4, 6, 8> (5);
+}
index 6eedca4f91f121eda1d73f7d0ef6d92ca541a40e..f41587fa21d719225dafcab8ef7243f471504553 100644 (file)
@@ -1036,7 +1036,13 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
 
     case OMP_CLAUSE_NUM_TEAMS:
       pp_string (pp, "num_teams(");
-      dump_generic_node (pp, OMP_CLAUSE_NUM_TEAMS_EXPR (clause),
+      if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (clause))
+       {
+         dump_generic_node (pp, OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (clause),
+                            spc, flags, false);
+         pp_colon (pp);
+       }
+      dump_generic_node (pp, OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (clause),
                         spc, flags, false);
       pp_right_paren (pp);
       break;
index 7320247e05f881ad64d184141aa104a21c65825d..9146d3e06de622f721eab12592e6cc3c8a9cf736 100644 (file)
@@ -331,7 +331,7 @@ unsigned const char omp_clause_num_ops[] =
   1, /* OMP_CLAUSE_DIST_SCHEDULE  */
   0, /* OMP_CLAUSE_INBRANCH  */
   0, /* OMP_CLAUSE_NOTINBRANCH  */
-  1, /* OMP_CLAUSE_NUM_TEAMS  */
+  2, /* OMP_CLAUSE_NUM_TEAMS  */
   1, /* OMP_CLAUSE_THREAD_LIMIT  */
   0, /* OMP_CLAUSE_PROC_BIND  */
   1, /* OMP_CLAUSE_SAFELEN  */
index c93d1b34f9b1ca0df521bb0e8de94bf1f1204ee6..6b63e2e0f5256240038fae7371c95609edbe999c 100644 (file)
@@ -1818,9 +1818,12 @@ class auto_suppress_location_wrappers
 #define OMP_CLAUSE_ALLOCATE_COMBINED(NODE) \
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ALLOCATE)->base.public_flag)
 
-#define OMP_CLAUSE_NUM_TEAMS_EXPR(NODE) \
+#define OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_TEAMS), 0)
 
+#define OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR(NODE) \
+  OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_TEAMS), 1)
+
 #define OMP_CLAUSE_THREAD_LIMIT_EXPR(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, \
                                                OMP_CLAUSE_THREAD_LIMIT), 0)
index 0546effcbcddf0135153d993c55d7bed25de4216..e8304a09a69e5bc559dcd13e9a9d507170e31f5a 100644 (file)
@@ -1,3 +1,10 @@
+2022-02-27  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2021-11-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * testsuite/libgomp.c-c++-common/teams-1.c: New test.
+
 2022-02-27  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
diff --git a/libgomp/testsuite/libgomp.c-c++-common/teams-1.c b/libgomp/testsuite/libgomp.c-c++-common/teams-1.c
new file mode 100644 (file)
index 0000000..76189ef
--- /dev/null
@@ -0,0 +1,26 @@
+#include <omp.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+  #pragma omp teams num_teams (5)
+  {
+    if (omp_get_num_teams () != 5)
+      abort ();
+    #pragma omp distribute dist_schedule(static,1)
+    for (int i = 0; i < 5; ++i)
+      if (omp_get_team_num () != i)
+       abort ();
+  }
+  #pragma omp teams num_teams (7 : 9)
+  {
+    if (omp_get_num_teams () < 7 || omp_get_num_teams () > 9)
+      abort ();
+    #pragma omp distribute dist_schedule(static,1)
+    for (int i = 0; i < omp_get_num_teams (); ++i)
+      if (omp_get_team_num () != i)
+       abort ();
+  }
+  return 0;
+}