https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122432
Bug ID: 122432
Summary: [Offloading][OpenMP][OpenACC] LTO/linker plugin:
Mismatch between host used symbol vs. device symbol
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Keywords: openacc, openmp
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: burnus at gcc dot gnu.org
CC: hjl.tools at gmail dot com
Target Milestone: ---
Created attachment 62638
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=62638&action=edit
tar.gz with 4 *.f90 files; look at 'build.sh' for how to build it / requires
offload-configured GCC + ld.bfd
This seems to be a BFD linker issue – which claims that a symbol is not used
when calling the claim_file_handler_v2 hook – but then still linking it.
This somehow relates to a common block in the same translation unit as the
unused offload code, even though it is not used at all.
The largely reduced test case can probably be reduced a bit more. In any case,
if run, it shows with a GPU:
libgomp: Cannot map target functions or variables (expected 2 + 0 + 1, have 2)
Thanks to Salvatore Filippone for reporting the issue + providing the testcase.
* * *
If one looks at the device assembly, there is on the offload side only:
d_inner_oacc_amax$0$_omp_fn$0 (for nvptx-none)
d_inner_oacc_amax.0._omp_fn.0 (for amdgcn-amdhsa)
However, on the host, there is additionally d_inner_oacc_mlt_v_2.0._omp_fn:
(gdb) p ((void**)__OFFLOAD_TABLE__)[0]
$8 = (void *) 0x401430 <d_inner_oacc_amax.0._omp_fn>
(gdb) p ((void**)__OFFLOAD_TABLE__)[1]
$9 = (void *) 0x401700 <d_inner_oacc_mlt_v_2.0._omp_fn>
(gdb) p ((void**)__OFFLOAD_TABLE__)[2]
$10 = (void *) 0x0
This issue is a bit similar to PR109128 (and vaguely related to PR116361).
* * *
If I add some stupid 'printf' debugging to the linker plugin, the result is the
following (only part that has '1' for the offloading flag):
DEBUG: ./liblocoa.a @ 644 - obj.found = 0, offload = 1, known-used: 0
DEBUG: ./liblocoa.a @ 2458 - obj.found = 0, offload = 1, known-used: 1
The output is from lto-plugin.c:1288 in the function 'claim_file_handler_v2':
__builtin_fprintf(stderr, "DEBUG: %s @ %lx - obj.found = %d, offload = %d,
known-used: %d\n", file->name, file->offset, obj.found, obj.offload,
known_used);
* * *
The common block contains 'mpi_fortran_argv_null_' (and others) and those
symbols are present in psb_d_oacc_mlt_v_2.o psb_d_oacc_vect_mod.o vectoacc.o.
Those are common blocks.
For some reason, the presence of the common blocks causes that the following
section in psb_d_oacc_mlt_v_2.s is still present in the final binary, even
though the linker claimed known_use = 0. Namely, psb_d_oacc_mlt_v.s contains
the following
.offload_func_table:
.quad d_inner_oacc_mlt_v.0._omp_fn.0
.section .gnu.offload_ind_funcs,"aw"
.align 8
.type .offload_ind_func_table, @object
.size .offload_ind_func_table, 0
(Ok to be there in .s file, but it should either be absent in the linked binary
or known_used = true in the linker-plugin call.) The associated .o file has the
following - which unsurprisingly looks also fine:
0000000000000000 t d_inner_oacc_mlt_v_2.0
00000000000002b8 t d_inner_oacc_mlt_v_2.0._omp_fn.0
...
0000000000000001 C mpi_fortran_argv_null_
...
0000000000000000 d .offload_func_table