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.