[Patch] OpenMP: Reject omp_{cgroup, pteam, thread}_mem_alloc for static vars in ALLOCATE directive [PR122892]

Tobias Burnus <[email protected]>
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.fortran
Message-ID <[email protected]>
This patch adds a missing check to C already present for Fortran,
except that the rules have been further tightened, hence, Fortran
is modified as well.

Comments before I push it later today?

* * *

The following is about the 'omp allocate' directive applied to
static variables, only; for those, only predefined allocators
are permitted in the 'omp allocate' directive. Additionally:

The predefined allocators omp_{cgroup,pteam,thread}_mem_alloc are
special in the sense that their access trait is not the full device
but only something smaller. That's ill-defined for global static
variables and was therefore restricted to local static variables,
where the allocation can be done the first time the procedure is
invoked. For cgroup lifetime/initialization is mostly clear but for
pteam/thread is becomes a bit murkier and if reading the current
wording such that the first tread invoking that function takes
care of it, threads of other teams cannot really access that
variable. [Could be fixed but needs thinking of the fine print
for a not so important feature. Hence, restricting is easier
for now on the specification side - and even more so on the
compiler side.]

Thus, those three predefined allocators are now disallowed also
for local static variables (→ OpenMP spec issue #4665, TR15 +
OpenMP 6.1).

In GCC, as documented, specifying an OpenMP memory allocator on a
static variable has no effect (besides honoring the alignment),
cf. https://gcc.gnu.org/onlinedocs/libgomp/Memory-allocation.html

Future: However, as the data is passed down to the compiler
backend, adding support for it in the future is simple. For instance,
omp_const_mem_alloc could be placed in offload code into special
memory: At least Nvidia's GPUs have memory that can be accessed
from multiple threads without requiring that the hardware ensures
cache consistency; that memory is used by classical GPUs to store
the texture.

Crossref: Instead of using omp_cgroup_mem_alloc, you can use
'omp groupprivate' to achieve a similar effect. (Likely, is is
only supported on offload devices [device_type(nohost)] and no
initializers are permitted, but still. Note that groupprivate
is not yet supported in GCC.)

Thanks,

Tobias
static-allocator.diff (text/x-patch, 29.3 KB)
OpenMP: Reject omp_{cgroup,pteam,thread}_mem_alloc for static vars in ALLOCATE directive [PR122892]

Using omp_{cgroup,pteam,thread}_mem_alloc for static variables was not
very useful as currently worded in the spec; hence, OpenMP 6.1 will
disallow it also for for local static variables, OpenMP 6.0 already
disallowed for other static variables. Cf. OpenMP specification
issue #4665.

For Fortran, the check is modified while for C the check was completely
missing. Both has been rectified by this commit. For C++, the allocate
directive still has to be added.

	PR c/122892

gcc/c/ChangeLog:

	* c-parser.cc (c_parser_omp_allocate): Reject
	omp_{cgroup,pteam,thread}_mem_alloc for static variables.

gcc/fortran/ChangeLog:

	* openmp.cc (gfc_resolve_omp_allocate): Reject
	omp_{cgroup,pteam,thread}_mem_alloc also for local static
	variables.

gcc/ChangeLog:

	* gimplify.cc (gimplify_scan_omp_clauses): Update for removed
	plural -S in GOMP_OMP_PREDEF_ALLOC_THREAD.

include/ChangeLog:

	* gomp-constants.h (GOMP_OMP_PREDEF_ALLOC_THREADS): Rename to ...
	(GOMP_OMP_PREDEF_ALLOC_THREAD): ... this.
	(GOMP_OMP_PREDEF_ALLOC_CGROUP, GOMP_OMP_PREDEF_ALLOC_PTEAM): Define
	with the value of omp_{cgroup,pteam}_mem_alloc

libgomp/ChangeLog:

	* allocator.c (_Static_assert): Add asserts for the values of
	GOMP_OMP_PREDEF_ALLOC_CGROUP and GOMP_OMP_PREDEF_ALLOC_PTEAM.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/allocate-static-3.f90: Modify to also
	disallow local static variables.
	* c-c++-common/gomp/allocate-20.c: New test.

 gcc/c/c-parser.cc                                  | 13 +++
 gcc/fortran/openmp.cc                              | 16 ++--
 gcc/gimplify.cc                                    |  2 +-
 gcc/testsuite/c-c++-common/gomp/allocate-20.c      | 99 ++++++++++++++++++++++
 .../gfortran.dg/gomp/allocate-static-3.f90         | 71 ++++++++--------
 include/gomp-constants.h                           |  6 +-
 libgomp/allocator.c                                |  8 +-
 7 files changed, 167 insertions(+), 48 deletions(-)

diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index e6f7104013b..4ded9661f58 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -23629,6 +23629,19 @@ c_parser_omp_allocate (c_parser *parser)
 			"%<allocator%> clause requires a predefined allocator as "
 			"%qD is static", var);
 	    }
+	  else if (allocator
+		   && (wi::eq_p (wi::to_widest (allocator),
+				 GOMP_OMP_PREDEF_ALLOC_CGROUP)
+		       || wi::eq_p (wi::to_widest (allocator),
+				    GOMP_OMP_PREDEF_ALLOC_PTEAM)
+		       || wi::eq_p (wi::to_widest (allocator),
+				    GOMP_OMP_PREDEF_ALLOC_THREAD)))
+	    {
+	      error_at (allocator_loc,
+			"%<allocator%> clause for static variable %qD must not "
+			"be %<omp_cgroup_mem_alloc%>, %<omp_pteam_mem_alloc%>, "
+			"or %<omp_thread_mem_alloc%>", var);
+	    }
 	}
       if (allocator)
 	{
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 18c67042740..65ec14ebadc 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -9063,24 +9063,22 @@ gfc_resolve_omp_allocate (gfc_namespace *ns, gfc_omp_namelist *list)
 		       &n->u2.allocator->where, com ? "/" : "",
 		       com ? n->sym->common_head->name : n->sym->name,
 		       com ? "/" : "", &n->where);
-	  /* Only local static variables might use omp_cgroup_mem_alloc (6),
+	  /* Static variables may not use omp_cgroup_mem_alloc (6),
 	     omp_pteam_mem_alloc (7), or omp_thread_mem_alloc (8).  */
-	  else if ((!ns->proc_name
-		    || ns->proc_name->attr.flavor == FL_PROGRAM
-		    || ns->proc_name->attr.flavor == FL_BLOCK_DATA
-		    || ns->proc_name->attr.flavor == FL_MODULE
-		    || com)
-		   && mpz_cmp_si (n->u2.allocator->value.integer,
+	  else if (mpz_cmp_si (n->u2.allocator->value.integer,
 				  6 /* cgroup */) >= 0
 		   && mpz_cmp_si (n->u2.allocator->value.integer,
 				  8 /* thread */) <= 0)
 	    {
+	      STATIC_ASSERT (GOMP_OMP_PREDEF_ALLOC_CGROUP == 6);
+	      STATIC_ASSERT (GOMP_OMP_PREDEF_ALLOC_PTEAM == 7);
+	      STATIC_ASSERT (GOMP_OMP_PREDEF_ALLOC_THREAD == 8);
 	      const char *alloc_name[] = {"omp_cgroup_mem_alloc",
 					  "omp_pteam_mem_alloc",
 					  "omp_thread_mem_alloc" };
 	      gfc_error ("Predefined allocator %qs in ALLOCATOR clause at %L, "
-			 "used for list item %<%s%s%s%> at %L, may only be used"
-			 " for local static variables",
+			 "used for list item %<%s%s%s%> at %L, may not be used"
+			 " for static variables",
 			 alloc_name[mpz_get_ui (n->u2.allocator->value.integer)
 				    - 6 /* cgroup */], &n->u2.allocator->where,
 			 com ? "/" : "",
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index dd5caf5662b..853a759df6b 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -14938,7 +14938,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 	  decl = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
 	  if (decl
 	      && TREE_CODE (decl) == INTEGER_CST
-	      && wi::eq_p (wi::to_widest (decl), GOMP_OMP_PREDEF_ALLOC_THREADS)
+	      && wi::eq_p (wi::to_widest (decl), GOMP_OMP_PREDEF_ALLOC_THREAD)
 	      && (code == OMP_TARGET || code == OMP_TASK || code == OMP_TASKLOOP))
 	    warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
 			"allocator with access trait set to %<thread%> "
diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-20.c b/gcc/testsuite/c-c++-common/gomp/allocate-20.c
new file mode 100644
index 00000000000..397d29a3599
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/allocate-20.c
@@ -0,0 +1,99 @@
+// { dg-do compile }
+
+typedef __UINTPTR_TYPE__ omp_uintptr_t;
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : omp_uintptr_t
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_allocator_handle_t __GOMP_UINTPTR_T_ENUM
+{ 
+  omp_null_allocator = 0,
+  omp_default_mem_alloc = 1,
+  omp_large_cap_mem_alloc = 2,
+  omp_const_mem_alloc = 3,
+  omp_high_bw_mem_alloc = 4,
+  omp_low_lat_mem_alloc = 5,
+  omp_cgroup_mem_alloc = 6,
+  omp_pteam_mem_alloc = 7,
+  omp_thread_mem_alloc = 8,
+  ompx_gnu_pinned_mem_alloc = 200,
+  ompx_gnu_managed_mem_alloc = 201,
+  __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+static int g0;
+static int g1;
+static int g2;
+static int g3;
+static int g4;
+static int g5;
+static int g6;
+static int g7;
+static int g8;
+static int g9;
+static int g10;
+
+#pragma omp allocate(g0) allocator(omp_null_allocator)  // { dg-error "'allocator' clause requires a predefined allocator as 'g0' is static" "" { target c } }
+#pragma omp allocate(g1) allocator(omp_default_mem_alloc)
+#pragma omp allocate(g2) allocator(omp_large_cap_mem_alloc)
+#pragma omp allocate(g3) allocator(omp_const_mem_alloc)
+#pragma omp allocate(g4) allocator(omp_high_bw_mem_alloc)
+#pragma omp allocate(g5) allocator(omp_low_lat_mem_alloc)
+#pragma omp allocate(g6) allocator(omp_cgroup_mem_alloc)  // { dg-error "'allocator' clause for static variable 'g6' must not be 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c } }
+#pragma omp allocate(g7) allocator(omp_pteam_mem_alloc)   // { dg-error "'allocator' clause for static variable 'g7' must not be 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c } }
+#pragma omp allocate(g8) allocator(omp_thread_mem_alloc)  // { dg-error "'allocator' clause for static variable 'g8' must not be 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c } }
+#pragma omp allocate(g9) allocator(ompx_gnu_pinned_mem_alloc)
+#pragma omp allocate(g10) allocator(ompx_gnu_managed_mem_alloc)
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+// { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+
+
+void local_static ()
+{
+  static int s0;
+  static int s1;
+  static int s2;
+  static int s3;
+  static int s4;
+  static int s5;
+  static int s6;
+  static int s7;
+  static int s8;
+  static int s9;
+  static int s10;
+
+  #pragma omp allocate(s0) allocator(omp_null_allocator)  // { dg-error "'allocator' clause requires a predefined allocator as 's0' is static" "" { target c } }
+  #pragma omp allocate(s1) allocator(omp_default_mem_alloc)
+  #pragma omp allocate(s2) allocator(omp_large_cap_mem_alloc)
+  #pragma omp allocate(s3) allocator(omp_const_mem_alloc)
+  #pragma omp allocate(s4) allocator(omp_high_bw_mem_alloc)
+  #pragma omp allocate(s5) allocator(omp_low_lat_mem_alloc)
+  #pragma omp allocate(s6) allocator(omp_cgroup_mem_alloc)  // { dg-error "'allocator' clause for static variable 's6' must not be 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c } }
+  #pragma omp allocate(s7) allocator(omp_pteam_mem_alloc)   // { dg-error "'allocator' clause for static variable 's7' must not be 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c } }
+  #pragma omp allocate(s8) allocator(omp_thread_mem_alloc)  // { dg-error "'allocator' clause for static variable 's8' must not be 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc', or 'omp_thread_mem_alloc'" "" { target c } }
+  #pragma omp allocate(s9) allocator(ompx_gnu_pinned_mem_alloc)
+  #pragma omp allocate(s10) allocator(ompx_gnu_managed_mem_alloc)
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+  // { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-11 }
+}
diff --git a/gcc/testsuite/gfortran.dg/gomp/allocate-static-3.f90 b/gcc/testsuite/gfortran.dg/gomp/allocate-static-3.f90
index 28a638c6f24..ae926688445 100644
--- a/gcc/testsuite/gfortran.dg/gomp/allocate-static-3.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/allocate-static-3.f90
@@ -5,7 +5,10 @@
 ! OpenMP 6.0 clarified that the omp_{cgroup,pteam,thread}_mem_alloc
 ! (i.e. those with access trait != device) may only be used for
 ! static local variables.
-! Check for this!
+!
+! Since OpenMP 6.1, omp_{cgroup,pteam,thread}_mem_alloc may not
+! be used for static variables, local static or not.
+! Cf. OpenMP Spec issue #4665
 
 module omp_lib_kinds
   use iso_c_binding, only: c_int, c_intptr_t
@@ -60,9 +63,9 @@ block data
   !$omp allocate(/b_i3/) allocator(omp_const_mem_alloc)
   !$omp allocate(/b_i4/) allocator(omp_high_bw_mem_alloc)
   !$omp allocate(/b_i5/) allocator(omp_low_lat_mem_alloc)
-  !$omp allocate(/b_i6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_i6/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_i7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_i7/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_i8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_i8/' at .2., may only be used for local static variables" }
+  !$omp allocate(/b_i6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_i6/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_i7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_i7/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_i8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_i8/' at .2., may not be used for static variables" }
 end block data
 
 block data my_block_data
@@ -92,9 +95,9 @@ block data my_block_data
   !$omp allocate(/b_j3/) allocator(omp_const_mem_alloc)
   !$omp allocate(/b_j4/) allocator(omp_high_bw_mem_alloc)
   !$omp allocate(/b_j5/) allocator(omp_low_lat_mem_alloc)
-  !$omp allocate(/b_j6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_j6/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_j7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_j7/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_j8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_j8/' at .2., may only be used for local static variables" }
+  !$omp allocate(/b_j6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_j6/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_j7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_j7/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_j8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_j8/' at .2., may not be used for static variables" }
 end block data my_block_data
 
 module m
@@ -117,18 +120,18 @@ module m
   !$omp allocate(a3) allocator(omp_const_mem_alloc)
   !$omp allocate(a4) allocator(omp_high_bw_mem_alloc)
   !$omp allocate(a5) allocator(omp_low_lat_mem_alloc)
-  !$omp allocate(a6) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item 'a6' at .2., may only be used for local static variables" }
-  !$omp allocate(a7) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item 'a7' at .2., may only be used for local static variables" }
-  !$omp allocate(a8) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item 'a8' at .2., may only be used for local static variables" }
+  !$omp allocate(a6) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item 'a6' at .2., may not be used for static variables" }
+  !$omp allocate(a7) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item 'a7' at .2., may not be used for static variables" }
+  !$omp allocate(a8) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item 'a8' at .2., may not be used for static variables" }
 
   !$omp allocate(/b_b1/) allocator(omp_default_mem_alloc)
   !$omp allocate(/b_b2/) allocator(omp_large_cap_mem_alloc)
   !$omp allocate(/b_b3/) allocator(omp_const_mem_alloc)
   !$omp allocate(/b_b4/) allocator(omp_high_bw_mem_alloc)
   !$omp allocate(/b_b5/) allocator(omp_low_lat_mem_alloc)
-  !$omp allocate(/b_b6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_b6/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_b7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_b7/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_b8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_b8/' at .2., may only be used for local static variables" }
+  !$omp allocate(/b_b6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_b6/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_b7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_b7/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_b8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_b8/' at .2., may not be used for static variables" }
 end
 
 program main
@@ -151,18 +154,18 @@ program main
   !$omp allocate(m3) allocator(omp_const_mem_alloc)
   !$omp allocate(m4) allocator(omp_high_bw_mem_alloc)
   !$omp allocate(m5) allocator(omp_low_lat_mem_alloc)
-  !$omp allocate(m6) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item 'm6' at .2., may only be used for local static variables" }
-  !$omp allocate(m7) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item 'm7' at .2., may only be used for local static variables" }
-  !$omp allocate(m8) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item 'm8' at .2., may only be used for local static variables" }
+  !$omp allocate(m6) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item 'm6' at .2., may not be used for static variables" }
+  !$omp allocate(m7) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item 'm7' at .2., may not be used for static variables" }
+  !$omp allocate(m8) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item 'm8' at .2., may not be used for static variables" }
 
   !$omp allocate(/b_n1/) allocator(omp_default_mem_alloc)
   !$omp allocate(/b_n2/) allocator(omp_large_cap_mem_alloc)
   !$omp allocate(/b_n3/) allocator(omp_const_mem_alloc)
   !$omp allocate(/b_n4/) allocator(omp_high_bw_mem_alloc)
   !$omp allocate(/b_n5/) allocator(omp_low_lat_mem_alloc)
-  !$omp allocate(/b_n6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_n6/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_n7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_n7/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_n8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_n8/' at .2., may only be used for local static variables" }
+  !$omp allocate(/b_n6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_n6/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_n7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_n7/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_n8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_n8/' at .2., may not be used for static variables" }
 
   block
     integer, save :: o1,o2,o3,o4,o5,o6,o7,o8
@@ -173,9 +176,9 @@ program main
     !$omp allocate(o3) allocator(omp_const_mem_alloc)
     !$omp allocate(o4) allocator(omp_high_bw_mem_alloc)
     !$omp allocate(o5) allocator(omp_low_lat_mem_alloc)
-    !$omp allocate(o6) allocator(omp_cgroup_mem_alloc)
-    !$omp allocate(o7) allocator(omp_pteam_mem_alloc)
-    !$omp allocate(o8) allocator(omp_thread_mem_alloc)
+    !$omp allocate(o6) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item 'o6' at .2., may not be used for static variables" }
+    !$omp allocate(o7) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item 'o7' at .2., may not be used for static variables" }
+    !$omp allocate(o8) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item 'o8' at .2., may not be used for static variables" }
   end block
 end
 
@@ -199,18 +202,18 @@ subroutine sub
   !$omp allocate(s3) allocator(omp_const_mem_alloc)
   !$omp allocate(s4) allocator(omp_high_bw_mem_alloc)
   !$omp allocate(s5) allocator(omp_low_lat_mem_alloc)
-  !$omp allocate(s6) allocator(omp_cgroup_mem_alloc)
-  !$omp allocate(s7) allocator(omp_pteam_mem_alloc)
-  !$omp allocate(s8) allocator(omp_thread_mem_alloc)
+  !$omp allocate(s6) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item 's6' at .2., may not be used for static variables" }
+  !$omp allocate(s7) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item 's7' at .2., may not be used for static variables" }
+  !$omp allocate(s8) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item 's8' at .2., may not be used for static variables" }
 
   !$omp allocate(/b_t1/) allocator(omp_default_mem_alloc)
   !$omp allocate(/b_t2/) allocator(omp_large_cap_mem_alloc)
   !$omp allocate(/b_t3/) allocator(omp_const_mem_alloc)
   !$omp allocate(/b_t4/) allocator(omp_high_bw_mem_alloc)
   !$omp allocate(/b_t5/) allocator(omp_low_lat_mem_alloc)
-  !$omp allocate(/b_t6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_t6/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_t7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_t7/' at .2., may only be used for local static variables" }
-  !$omp allocate(/b_t8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_t8/' at .2., may only be used for local static variables" }
+  !$omp allocate(/b_t6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_t6/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_t7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_t7/' at .2., may not be used for static variables" }
+  !$omp allocate(/b_t8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_t8/' at .2., may not be used for static variables" }
 contains
   integer function func()
     integer, save :: q1,q2,q3,q4,q5,q6,q7,q8
@@ -229,17 +232,17 @@ contains
     !$omp allocate(q3) allocator(omp_const_mem_alloc)
     !$omp allocate(q4) allocator(omp_high_bw_mem_alloc)
     !$omp allocate(q5) allocator(omp_low_lat_mem_alloc)
-    !$omp allocate(q6) allocator(omp_cgroup_mem_alloc)
-    !$omp allocate(q7) allocator(omp_pteam_mem_alloc)
-    !$omp allocate(q8) allocator(omp_thread_mem_alloc)
+    !$omp allocate(q6) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item 'q6' at .2., may not be used for static variables" }
+    !$omp allocate(q7) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item 'q7' at .2., may not be used for static variables" }
+    !$omp allocate(q8) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item 'q8' at .2., may not be used for static variables" }
 
     !$omp allocate(/b_r1/) allocator(omp_default_mem_alloc)
     !$omp allocate(/b_r2/) allocator(omp_large_cap_mem_alloc)
     !$omp allocate(/b_r3/) allocator(omp_const_mem_alloc)
     !$omp allocate(/b_r4/) allocator(omp_high_bw_mem_alloc)
     !$omp allocate(/b_r5/) allocator(omp_low_lat_mem_alloc)
-    !$omp allocate(/b_r6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_r6/' at .2., may only be used for local static variables" }
-    !$omp allocate(/b_r7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_r7/' at .2., may only be used for local static variables" }
-    !$omp allocate(/b_r8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_r8/' at .2., may only be used for local static variables" }
+    !$omp allocate(/b_r6/) allocator(omp_cgroup_mem_alloc)  ! { dg-error "Predefined allocator 'omp_cgroup_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_r6/' at .2., may not be used for static variables" }
+    !$omp allocate(/b_r7/) allocator(omp_pteam_mem_alloc)   ! { dg-error "Predefined allocator 'omp_pteam_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_r7/' at .2., may not be used for static variables" }
+    !$omp allocate(/b_r8/) allocator(omp_thread_mem_alloc)  ! { dg-error "Predefined allocator 'omp_thread_mem_alloc' in ALLOCATOR clause at .1., used for list item '/b_r8/' at .2., may not be used for static variables" }
   end function
 end subroutine
diff --git a/include/gomp-constants.h b/include/gomp-constants.h
index 0a0761043f9..d0d5ba7f2af 100644
--- a/include/gomp-constants.h
+++ b/include/gomp-constants.h
@@ -402,8 +402,10 @@ enum gomp_map_kind
 #define GOMP_OMPX_PREDEF_MEMSPACE_MIN	200
 #define GOMP_OMPX_PREDEF_MEMSPACE_MAX	200
 
-/* Predefined allocator with access == thread.  */
-#define GOMP_OMP_PREDEF_ALLOC_THREADS	8
+/* Predefined allocator with access == cgroup, pteam, and thread.  */
+#define GOMP_OMP_PREDEF_ALLOC_CGROUP	6
+#define GOMP_OMP_PREDEF_ALLOC_PTEAM	7
+#define GOMP_OMP_PREDEF_ALLOC_THREAD	8
 
 /* Flag values for OpenMP 'requires' directive features.  */
 // compiler use only: OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER  0xf
diff --git a/libgomp/allocator.c b/libgomp/allocator.c
index 8fdaf9bd198..d2e88d97846 100644
--- a/libgomp/allocator.c
+++ b/libgomp/allocator.c
@@ -108,8 +108,12 @@ _Static_assert (GOMP_OMPX_PREDEF_ALLOC_MIN == ompx_gnu_min_predefined_alloc,
 		"GOMP_OMPX_PREDEF_ALLOC_MIN == ompx_gnu_min_predefined_alloc");
 _Static_assert (GOMP_OMPX_PREDEF_ALLOC_MAX == ompx_gnu_max_predefined_alloc,
 		"GOMP_OMPX_PREDEF_ALLOC_MAX == ompx_gnu_max_predefined_alloc");
-_Static_assert (GOMP_OMP_PREDEF_ALLOC_THREADS == omp_thread_mem_alloc,
-		"GOMP_OMP_PREDEF_ALLOC_THREADS == omp_thread_mem_alloc");
+_Static_assert (GOMP_OMP_PREDEF_ALLOC_CGROUP == omp_cgroup_mem_alloc,
+		"GOMP_OMP_PREDEF_ALLOC_CGROUP == omp_cgroup_mem_alloc");
+_Static_assert (GOMP_OMP_PREDEF_ALLOC_PTEAM == omp_pteam_mem_alloc,
+		"GOMP_OMP_PREDEF_ALLOC_PTEAM == omp_pteam_mem_alloc");
+_Static_assert (GOMP_OMP_PREDEF_ALLOC_THREAD == omp_thread_mem_alloc,
+		"GOMP_OMP_PREDEF_ALLOC_THREAD == omp_thread_mem_alloc");
 
 #define omp_max_predefined_mem_space omp_low_lat_mem_space
 #define ompx_gnu_min_predefined_mem_space ompx_gnu_managed_mem_space
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.