https://gcc.gnu.org/g:3d72e50caebf232fdd7f70613616ca4fd4fb472b
commit r15-5886-g3d72e50caebf232fdd7f70613616ca4fd4fb472b Author: Tobias Burnus <tbur...@baylibre.com> Date: Tue Dec 3 11:02:03 2024 +0100 OpenMP: 'allocate' directive - fixes for 'alignof' and [[omp::decl]] Fixed a check to permit [[omp::decl(allocate,...)]] parsing in C. Additionaly, we discussed that 'allocate align' should not affect 'alignof' to avoid issues like with: int a; _Alignas(_Alignof(a)) int b; #pragma omp allocate(a) align(128) _Alignas(_Alignof(a)) int c; Thus, the alignment is no longer set in the C and Fortran front ends, but for static variables now in varpool_node::finalize_decl. (For stack variables, the alignment is handled in gimplify_bind_expr.) NOTE: 'omp allocate' is not yet supported in C++. gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_allocate): Only check scope if not in_omp_decl_attribute. Remove setting the alignment. gcc/ChangeLog: * cgraphunit.cc (varpool_node::finalize_decl): Set alignment based on OpenMP's 'omp allocate' attribute/directive. gcc/fortran/ChangeLog: * trans-decl.cc (gfc_finish_var_decl): Remove setting the alignment. libgomp/ChangeLog: * libgomp.texi (Memory allocation): Mention (non-)effect of 'align' on _Alignof. * testsuite/libgomp.c/allocate-7.c: New test. gcc/testsuite/ChangeLog: * c-c++-common/gomp/allocate-18.c: Check that alignof is unaffected by 'omp allocate'. * c-c++-common/gomp/allocate-19.c: Likewise. Diff: --- gcc/c/c-parser.cc | 5 +-- gcc/cgraphunit.cc | 12 ++++++ gcc/fortran/trans-decl.cc | 3 -- gcc/testsuite/c-c++-common/gomp/allocate-18.c | 6 +-- gcc/testsuite/c-c++-common/gomp/allocate-19.c | 10 ++--- libgomp/libgomp.texi | 6 +++ libgomp/testsuite/libgomp.c/allocate-7.c | 54 +++++++++++++++++++++++++++ 7 files changed, 81 insertions(+), 15 deletions(-) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 0acba0542df6..a7719acf0bf2 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -22158,7 +22158,7 @@ c_parser_omp_allocate (c_parser *parser) "%<allocate%> directive", var); continue; } - if (!c_check_in_current_scope (var)) + if (!parser->in_omp_decl_attribute && !c_check_in_current_scope (var)) { error_at (OMP_CLAUSE_LOCATION (nl), "%<allocate%> directive must be in the same scope as %qD", @@ -22199,9 +22199,6 @@ c_parser_omp_allocate (c_parser *parser) = {EXPR_LOC_OR_LOC (allocator, OMP_CLAUSE_LOCATION (nl)), var}; walk_tree (&allocator, c_check_omp_allocate_allocator_r, &data, NULL); } - if (alignment) - SET_DECL_ALIGN (var, BITS_PER_UNIT * MAX (tree_to_uhwi (alignment), - DECL_ALIGN_UNIT (var))); DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"), build_tree_list (allocator, alignment), DECL_ATTRIBUTES (var)); diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc index d60ebc1c9884..e954e889960b 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -983,6 +983,18 @@ varpool_node::finalize_decl (tree decl) && !DECL_ARTIFICIAL (node->decl))) node->force_output = true; + if (flag_openmp) + { + tree attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl)); + if (attr) + { + tree align = TREE_VALUE (TREE_VALUE (attr)); + if (align) + SET_DECL_ALIGN (decl, MAX (tree_to_uhwi (align) * BITS_PER_UNIT, + DECL_ALIGN (decl))); + } + } + if (symtab->state == CONSTRUCTION && (node->needed_p () || node->referred_to_p ())) enqueue_node (node); diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index a62fe3f0441c..d69c8430484a 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -830,9 +830,6 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym) tree alloc = gfc_conv_constant_to_tree (n->u2.allocator); tree align = (n->u.align ? gfc_conv_constant_to_tree (n->u.align) : NULL_TREE); - if (align != NULL_TREE) - SET_DECL_ALIGN (decl, MAX (tree_to_uhwi (align), - DECL_ALIGN_UNIT (decl)) * BITS_PER_UNIT); DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("omp allocate"), build_tree_list (alloc, align), DECL_ATTRIBUTES (decl)); diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-18.c b/gcc/testsuite/c-c++-common/gomp/allocate-18.c index 4182f7ee37ec..93c5aca29a7c 100644 --- a/gcc/testsuite/c-c++-common/gomp/allocate-18.c +++ b/gcc/testsuite/c-c++-common/gomp/allocate-18.c @@ -17,14 +17,14 @@ typedef enum omp_allocator_handle_t void test0 () { - int A1[5]; + int A1[5], B1[5]; #pragma omp allocate(A1) align(128) allocator(omp_default_mem_alloc) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ #ifndef __cplusplus - _Static_assert (_Alignof(A1) == 128, "wrong alignment"); + _Static_assert (_Alignof(A1) == _Alignof(B1), "wrong alignment"); #elif __cplusplus >= 201103L - static_assert (alignof(A1) == 128, "wrong alignment"); /* { dg-bogus "static assertion failed: wrong alignment" "" { xfail { c++ && { ! c++98_only } } } } */ + static_assert (alignof(A1) == alignof(B1), "wrong alignment"); #endif } diff --git a/gcc/testsuite/c-c++-common/gomp/allocate-19.c b/gcc/testsuite/c-c++-common/gomp/allocate-19.c index ad3493d8c172..5c5fc008b2fa 100644 --- a/gcc/testsuite/c-c++-common/gomp/allocate-19.c +++ b/gcc/testsuite/c-c++-common/gomp/allocate-19.c @@ -19,14 +19,14 @@ typedef enum omp_allocator_handle_t __omp_allocator_handle_t_max__ = __UINTPTR_MAX__ } omp_allocator_handle_t; -static int A1[5] = {1,2,3,4,5}; +static int A1[5] = {1,2,3,4,5}, B1[5]; #pragma omp allocate(A1) align(128) allocator(omp_default_mem_alloc) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ #ifndef __cplusplus -_Static_assert (_Alignof(A1) == 128, "wrong alignment"); +_Static_assert (_Alignof(A1) == _Alignof(B1), "wrong alignment"); #elif __cplusplus >= 201103L -static_assert (alignof(A1) == 128, "wrong alignment"); /* { dg-bogus "static assertion failed: wrong alignment" "" { xfail { c++ && { ! c++98_only } } } } */ +static_assert (alignof(A1) == alignof(B1), "wrong alignment"); #endif @@ -49,9 +49,9 @@ get () /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target c++ } .-1 } */ #ifndef __cplusplus - _Static_assert (_Alignof(q) == 1024, "wrong alignment"); + _Static_assert (_Alignof(q) == _Alignof(int), "wrong alignment"); #elif __cplusplus >= 201103L - static_assert (alignof(q) == 1024, "wrong alignment"); /* { dg-bogus "static assertion failed: wrong alignment" "" { xfail { c++ && { ! c++98_only } } } } */ + static_assert (alignof(q) == alignof(int), "wrong alignment"); #endif q += 1; diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index fe291208cfee..453c35679077 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -6731,6 +6731,12 @@ The description below applies to: compiled with @option{-fopenmp-allocators}. Additionally, all files that might explicitly or implicitly deallocate memory allocated that way must also be compiled with that option. +@item The used alignment is the maximum of the value the @code{align} clause + and the alignment of the type after honoring, if present, the + @code{aligned} (@code{GNU::aligned}) attribute and C's @code{_Alignas} + and C++'s @code{alignas}. However, the @code{align} clause of the + @code{allocate} directive has no effect on the value of C's + @code{_Alignof} and C++'s @code{alignof}. @end itemize For the available predefined allocators and, as applicable, their associated diff --git a/libgomp/testsuite/libgomp.c/allocate-7.c b/libgomp/testsuite/libgomp.c/allocate-7.c new file mode 100644 index 000000000000..e11b8eb32c08 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/allocate-7.c @@ -0,0 +1,54 @@ +/* TODO: move to ../libgomp.c-c++-common once C++ is implemented. */ +/* NOTE: { target c } is unsupported with with the C compiler. */ + +/* { dg-do run } */ + +#include <omp.h> + +int AAA [[omp::decl(allocate,allocator(omp_low_lat_mem_alloc),align(4096))]]; + +#ifndef __cplusplus + _Static_assert (_Alignof(AAA) == _Alignof(int), "wrong alignment"); +#elif __cplusplus >= 201103L + static_assert (alignof(AAA) == _Alignof(int), "wrong alignment"); +#endif + + +void test0 () +{ + int A1[5], B1; + #pragma omp allocate(A1, B1) align(512) allocator(omp_default_mem_alloc) + +#ifndef __cplusplus + _Static_assert (_Alignof(A1) == _Alignof(int[5]), "wrong alignment"); + _Static_assert (_Alignof(B1) == _Alignof(int), "wrong alignment"); +#elif __cplusplus >= 201103L + static_assert (alignof(A1) == alignof(int[5]), "wrong alignment"); + static_assert (alignof(B1) == alignof(int), "wrong alignment"); +#endif + + if (((__UINTPTR_TYPE__) &A1 % 512) != 0) + __builtin_abort (); + if (((__UINTPTR_TYPE__) &B1 % 512) != 0) + __builtin_abort (); +} + +int main() +{ + static int BBB [[omp::decl(allocate,allocator(omp_low_lat_mem_alloc),align(4096))]]; + +#ifndef __cplusplus + _Static_assert (_Alignof(AAA) == _Alignof(int), "wrong alignment"); +#elif __cplusplus >= 201103L + static_assert (alignof(AAA) == alignof(int), "wrong alignment"); +#endif + + if (((__UINTPTR_TYPE__) &AAA % 4096) != 0) + __builtin_abort (); + if (((__UINTPTR_TYPE__) &BBB % 4096) != 0) + __builtin_abort (); + + test0 (); + + return 0; +}