https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94251

            Bug ID: 94251
           Summary: [OpenMP] 'target link' fails at run time /
                    libgomp.c/target-link-1.c fails on GCN
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Keywords: openmp, wrong-code
          Severity: normal
          Priority: P3
         Component: libgomp
          Assignee: unassigned at gcc dot gnu.org
          Reporter: burnus at gcc dot gnu.org
                CC: jakub at gcc dot gnu.org
  Target Milestone: ---

Follow-up to PR 94233.

The test case libgomp.c/target-link-1.c fails with AMDGCN with:
  "libgomp: Cannot map target variables (size mismatch)"

------------------------

That's in libgomp/target.c's gomp_load_image_to_device:

  /* Most significant bit of the size in host and target tables marks
     "omp declare target link" variables.  */
  const uintptr_t link_bit = 1ULL << (sizeof (uintptr_t) * __CHAR_BIT__ - 1);
  const uintptr_t size_mask = ~link_bit;

      struct addr_pair *target_var = &target_table[num_funcs + i];
      uintptr_t target_size = target_var->end - target_var->start;

      if ((uintptr_t) host_var_table[i * 2 + 1] != target_size)
        gomp_fatal ("Cannot map target variables (size mismatch)");

-----------------------

The code clearly assumes that the link_bit is also present in target_size –
which is not only visible in the quoted condition but also for:

      k->refcount = target_size & link_bit ? REFCOUNT_LINK : REFCOUNT_INFINITY;

While for the host data, that's not assumed as one masks the data:

      k->host_end
        = k->host_start + (size_mask & (uintptr_t) host_var_table[i * 2 + 1]);

I think it should be:
* no link mask in target_var->end / target_size
* Use 'host_var_table[i*2+1] & link_bit' in the refcount expression
* Use '& link_bit' for the size comparison. 

------------------------

The passed arguments are fine:
(gdb) p host_var_table[1]
$15 = (void *) 0x8000000000000008
(gdb) p host_var_table[3]
$16 = (void *) 0x80000000000000d8
(gdb) p host_var_table[5]
$17 = (void *) 0x4
(gdb) p host_var_table[7]
$18 = (void *) 0x8000000000000004

Namely: 'd' = 2*int = 8, 'c' = 27*double = 216 = 0xD8, 'a' and 'b' being
int=4.,
'b' is 'to', the rest is 'link'.

However, at least with AMDGCN, target_size == 8 for all variables. At a glance,
the code in GOMP_OFFLOAD_load_image looks fine, but:

image_desc->global_variables[i]->name is "d_linkptr" and not "d".


That variable is generated by lto/lto.c's offload_handle_link_vars as

        tree type = build_pointer_type (TREE_TYPE (var->decl));

where var->decl is "d" in this case.

Thus, it is not surprising that the size is always 8.

 * * *

Looking at the other plugins, they seems to work mostly likewise [get bit size
correctly]:

* hsa: global variables not processed in load_image, i.e.
  target_table not updated for the global variables!
* nvptx: cuModuleGetGlobal called, look fine.

Reply via email to