https://gcc.gnu.org/g:9e2e40f4ed8f0797963a0166d2568d23c2d25024

commit r17-2448-g9e2e40f4ed8f0797963a0166d2568d23c2d25024
Author: Tobias Burnus <[email protected]>
Date:   Thu Jul 16 12:11:38 2026 +0200

    OpenMP: uses_allocators - fix Fortran memspace use + multiple clauses 
[PR126279]
    
    The memspace modifier to uses_allocators was converted in Fortran not to an
    integer number but to an external variable - which failed then at link time.
    
    Additionally, it turned out that - at least with host fallback - multiple
    uses_allocator clauses aren't supported as newer ones overrode previous 
ones;
    shifting it by gomp_omp_allocator_data_size data helped.
    
    OpenMP requires 'a constant array, have constant values' for C/C++ and for
    Fortran a 'named constant of rank one'; it turned out that the FEs already
    generate, e.g.
       static struct omp_alloctrait_t traits[1] = {{.key=2, .value=1024}};
    which can be directly passed to the runtime library - no need to expand the
    initializer values into a new variable and then take the address of that 
one.
    
    For C/C++, this might be new since commit r17-2414-g9e9e22587f7954
    that set calls 'mark_exp_read' to avoid an 'unused but set' warning for the
    traits variable [not checked] - but in any case it is now consistent.
    
            PR fortran/126279
    
    gcc/fortran/ChangeLog:
    
            * trans-openmp.cc (gfc_trans_omp_clauses): Convert memspace constant
            to an integer not to an external variable.
    
    gcc/ChangeLog:
    
            * omp-low.cc (lower_omp_target): Avoid creating a second static 
const
            variable for the trait array used by uses_allocators.
    
    libgomp/ChangeLog:
    
            * target.c (copy_firstprivate_data): After storing  
users_allocators'
            allocator, shift the offset by its storage size to avoid overriding.
            * testsuite/libgomp.fortran/uses_allocators-1.f90: Use kind c_size_t
            instead of kind 8 for 32bit compatibility.
            * testsuite/libgomp.fortran/uses_allocators-4.f90: Update expected
            tree dump.
            * testsuite/libgomp.fortran/uses_allocators-7.f90: Extend testcase 
now
            that user-defined allocators are supported by uses_allocators.

Diff:
---
 gcc/fortran/trans-openmp.cc                        |  8 ++++++--
 gcc/omp-low.cc                                     | 12 ------------
 libgomp/target.c                                   |  1 +
 .../libgomp.fortran/uses_allocators-1.f90          |  2 +-
 .../libgomp.fortran/uses_allocators-4.f90          |  8 ++++----
 .../libgomp.fortran/uses_allocators-7.f90          | 22 +++++++++++++++++++---
 6 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 7243301cae0b..aa4e8ebfa239 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -5494,9 +5494,13 @@ gfc_trans_omp_clauses (stmtblock_t *block, 
gfc_omp_clauses *clauses,
              OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR(node) = t;
              if (n->u.memspace_sym)
                {
+                 gcc_checking_assert (n->u.memspace_sym->attr.flavor
+                                      == FL_PARAMETER
+                                      && !n->u.memspace_sym->attr.dimension);
                  n->u.memspace_sym->attr.referenced = true;
-                 OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (node)
-                   = gfc_get_symbol_decl (n->u.memspace_sym);
+                 gfc_init_se (&se, NULL);
+                 gfc_conv_expr (&se, n->u.memspace_sym->value);
+                 OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (node) = se.expr;
                }
              if (n->u2.traits_sym)
                {
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 33082fba1a36..4bab2c56a23d 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -14051,21 +14051,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, 
omp_context *ctx)
                ntraits = integer_zero_node;
                traits_var = null_pointer_node;
              }
-           else if (DECL_INITIAL (traits))
-             {
-               location_t loc = OMP_CLAUSE_LOCATION (c);
-               ntraits = array_type_nelts_top (TREE_TYPE (traits));
-               tree t = DECL_INITIAL (traits);
-               t = get_initialized_tmp_var (t, &ilist, NULL);
-               traits_var = build_fold_addr_expr_loc (loc, t);
-             }
            else
              {
-               /* This happens for VLAs, which probably aren't useful
-                  because they can't be const initialized in the same
-                  scope....  is there something else?  */
                location_t loc = OMP_CLAUSE_LOCATION (c);
-               gcc_assert (TREE_CODE (TREE_TYPE (traits)) == ARRAY_TYPE);
                ntraits = array_type_nelts_top (TREE_TYPE (traits));
                traits_var = build_fold_addr_expr_loc (loc, traits);
              }
diff --git a/libgomp/target.c b/libgomp/target.c
index e49eacc00713..0f5091521200 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -3282,6 +3282,7 @@ copy_firstprivate_data (char *tgt, size_t mapnum, void 
**hostaddrs,
                                                           tgt + tgt_size,
                                                           hostaddrs[i]);
        hostaddrs[i] = (void *) allocator;
+       tgt_size += gomp_omp_allocator_data_size;
       }
 }
 
diff --git a/libgomp/testsuite/libgomp.fortran/uses_allocators-1.f90 
b/libgomp/testsuite/libgomp.fortran/uses_allocators-1.f90
index cdabbed04e4f..329723a065f5 100644
--- a/libgomp/testsuite/libgomp.fortran/uses_allocators-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/uses_allocators-1.f90
@@ -10,7 +10,7 @@ integer(omp_allocator_handle_kind) :: var
 !$omp target uses_allocators(memspace(omp_default_mem_space), traits(mem2) : 
var) defaultmap(none)
 block;
 type(c_ptr) ::c
-c = omp_alloc(omp_default_mem_space, 20_8)
+c = omp_alloc(omp_default_mem_space, 20_c_size_t)
 end block
 !$omp target uses_allocators(omp_default_mem_alloc, var(mem2))  ! { dg-warning 
"The specification of arguments to 'uses_allocators' at \\(1\\) where each item 
is of the form 'allocator\\(traits\\)' is deprecated since OpenMP 5.2; instead 
use 'uses_allocators\\(traits\\(mem2\\): var\\)' \\\[-Wdeprecated-openmp\\\]" }
 block; end block
diff --git a/libgomp/testsuite/libgomp.fortran/uses_allocators-4.f90 
b/libgomp/testsuite/libgomp.fortran/uses_allocators-4.f90
index 0efdc9ef54b0..8338bb2d0306 100644
--- a/libgomp/testsuite/libgomp.fortran/uses_allocators-4.f90
+++ b/libgomp/testsuite/libgomp.fortran/uses_allocators-4.f90
@@ -48,12 +48,12 @@ end program main
 ! { dg-final { scan-tree-dump "pragma omp target" "original" } }
 ! { dg-final { scan-tree-dump "pragma omp target 
uses_allocators\\(memspace\\(\\), traits\\(traits_array\\) : bar\\) 
uses_allocators\\(memspace\\(\\), traits\\(traits_array\\) : foo\\)" "original" 
} }
 ! { dg-final { scan-tree-dump "pragma omp target 
uses_allocators\\(memspace\\(\\), traits\\(traits_array\\) : bar\\)" "original" 
} }
-! { dg-final { scan-tree-dump "pragma omp target 
uses_allocators\\(memspace\\(omp_low_lat_mem_space\\), traits\\(\\) : bar\\)" 
"original" } }
-! { dg-final { scan-tree-dump "pragma omp target 
uses_allocators\\(memspace\\(omp_high_bw_mem_space\\), traits\\(traits_array\\) 
: bar\\)" "original" } }
+! { dg-final { scan-tree-dump "pragma omp target 
uses_allocators\\(memspace\\(4\\), traits\\(\\) : bar\\)" "original" } }
+! { dg-final { scan-tree-dump "pragma omp target 
uses_allocators\\(memspace\\(3\\), traits\\(traits_array\\) : bar\\)" 
"original" } }
 
 ! { dg-final { scan-tree-dump "pragma omp target num_teams\\(-2\\) 
thread_limit\\(0\\) allocate\\(allocator\\(bar\\):arr\\) 
uses_allocators\\(memspace\\(\\), traits\\(\\) : bar\\)" "gimple" } }
 ! { dg-final { scan-tree-dump "pragma omp target" "gimple" } }
 ! { dg-final { scan-tree-dump "pragma omp target num_teams\\(-2\\) 
thread_limit\\(0\\) uses_allocators\\(memspace\\(\\), traits\\(traits_array\\) 
: bar\\) uses_allocators\\(memspace\\(\\), traits\\(traits_array\\) : foo\\)" 
"gimple" } }
 ! { dg-final { scan-tree-dump "pragma omp target num_teams\\(-2\\) 
thread_limit\\(0\\) uses_allocators\\(memspace\\(\\), traits\\(traits_array\\) 
: bar\\)" "gimple" } }
-! { dg-final { scan-tree-dump "pragma omp target num_teams\\(-2\\) 
thread_limit\\(0\\) uses_allocators\\(memspace\\(omp_low_lat_mem_space\\), 
traits\\(\\) : bar\\)" "gimple" } }
-! { dg-final { scan-tree-dump "pragma omp target num_teams\\(-2\\) 
thread_limit\\(0\\) uses_allocators\\(memspace\\(omp_high_bw_mem_space\\), 
traits\\(traits_array\\) : bar\\)" "gimple" } }
+! { dg-final { scan-tree-dump "pragma omp target num_teams\\(-2\\) 
thread_limit\\(0\\) uses_allocators\\(memspace\\(4\\), traits\\(\\) : bar\\)" 
"gimple" } }
+! { dg-final { scan-tree-dump "pragma omp target num_teams\\(-2\\) 
thread_limit\\(0\\) uses_allocators\\(memspace\\(3\\), traits\\(traits_array\\) 
: bar\\)" "gimple" } }
diff --git a/libgomp/testsuite/libgomp.fortran/uses_allocators-7.f90 
b/libgomp/testsuite/libgomp.fortran/uses_allocators-7.f90
index d0a603b5ced1..7605978c2b3d 100644
--- a/libgomp/testsuite/libgomp.fortran/uses_allocators-7.f90
+++ b/libgomp/testsuite/libgomp.fortran/uses_allocators-7.f90
@@ -9,13 +9,27 @@ program main
   integer(omp_allocator_handle_kind) :: my_alloc, my, my2, my3, my4
   type(omp_alloctrait), parameter :: trait(*) = 
[omp_alloctrait(omp_atk_alignment, 128)]
   type(omp_alloctrait), parameter :: t(*) = [omp_alloctrait:: ]
-  type(omp_alloctrait), parameter :: t2(*) = [omp_alloctrait:: ]
+  type(omp_alloctrait), parameter :: t2(*) = [omp_alloctrait:: 
omp_alloctrait(omp_atk_alignment, 1024)]
 
-  ! FIXME - improve check that that ';' is handled
+  my = -1; my2 = -2; my3 = -3; my4 = -4
   !$omp target uses_allocators(traits(t), memspace(omp_high_bw_mem_space) : 
my; omp_default_mem_alloc, omp_null_allocator; my2; traits(t2) : my3; 
memspace(omp_large_cap_mem_space) : my4)
   block
+    integer, pointer :: ip3(:)
+    type(c_ptr) :: c1, c2, c3, c4
+    c1 = omp_alloc (c_sizeof(x) * 1, my)
+    c2 = omp_alloc (c_sizeof(x) * 2, my2)
+    c3 = omp_alloc (c_sizeof(x) * 3, my3)
+    c4 = omp_alloc (c_sizeof(x) * 4, my4)
+    call c_f_pointer(c3, ip3, shape=[3])
+    if (mod (TRANSFER (loc(ip3), iptr), 1024) /= 0) &
+        stop 1
+    call omp_free (c1, omp_null_allocator)
+    call omp_free (c2, omp_null_allocator)
+    call omp_free (c3, omp_null_allocator)
+    call omp_free (c4, omp_null_allocator)
   end block
 
+  x = 1; xbuf = 0
   !$omp target uses_allocators(omp_low_lat_mem_alloc) map(tofrom: x, xbuf) 
defaultmap(none)
     !$omp parallel allocate(allocator(omp_low_lat_mem_alloc), align(128): x, 
xbuf) if(.false.) firstprivate(x, xbuf)
       if (mod (TRANSFER (loc(x), iptr), 128) /= 0) &
@@ -55,4 +69,6 @@ end
 
 ! { dg-final { scan-tree-dump-times "#pragma omp target 
.*uses_allocators\\(memspace\\(\\), traits\\(trait\\) : my_alloc\\)" 1 "gimple" 
} }
 ! { dg-final { scan-tree-dump-times "#pragma omp target 
.*uses_allocators\\(memspace\\(\\), traits\\(\\) : my_alloc\\)" 1 "gimple" } }
-! { dg-final { scan-tree-dump-times "#pragma omp target 
.*uses_allocators\\(memspace\\(1\\), traits\\(\\) : my4\\) 
uses_allocators\\(memspace\\(\\), traits\\(t2\\) : my3\\) 
uses_allocators\\(memspace\\(\\), traits\\(\\) : my2\\) 
uses_allocators\\(memspace\\(3\\), traits\\(t\\) : my\\)" 1 "original" { xfail 
*-*-* }  } }
+
+! { dg-final { scan-tree-dump-times "#pragma omp target 
uses_allocators\\(memspace\\(3\\), traits\\(t\\) : my\\) 
uses_allocators\\(memspace\\(\\), traits\\(\\) : 0B\\) 
uses_allocators\\(memspace\\(\\), traits\\(\\) : my2\\) 
uses_allocators\\(memspace\\(\\), traits\\(t2\\) : my3\\) 
uses_allocators\\(memspace\\(1\\), traits\\(\\) : my4\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target num_teams\\(-2\\) 
thread_limit\\(0\\) uses_allocators\\(memspace\\(3\\), traits\\(t\\) : my\\) 
uses_allocators\\(memspace\\(\\), traits\\(\\) : my2\\) 
uses_allocators\\(memspace\\(\\), traits\\(t2\\) : my3\\) 
uses_allocators\\(memspace\\(1\\), traits\\(\\) : my4\\)" 1 "gimple" } }

Reply via email to