Created attachment 58511 [details] Fortran testcase – requires '-fopenmp' and configured offloading - and patch for PR115559 gimple_regimplify_operands doesn't expand the value expression of 'arr2' in: MEM <uint128_t> [(c_char * {ref-all})&arr2] with arr2 having the value expression: value-expr <mem_ref 0x7ffff72ed9d8 type <array_type 0x7ffff72e9540> arg:0 <var_decl 0x7ffff72f21b0 arr2$13$linkptr> arg:1 <integer_cst 0x7ffff72d8ac8 constant 0>>> The code is produced for the attached code, which requires offloading, -fopenmp and the patch for PR fortran/115559. While 'omp declare target link(arr2)' has no direct effect on the host code, it replaces on the device a variable such as int arr[4]; by int *arr$linkptr; and all user of arr by (arr$linkref[0]). On the device side, the following code is produced: MEM <uint128_t> [(c_char * {ref-all})&arr2] = _7; _2 = arr2[_1]; the replacement of the latter works: _20 = arr2.13.linkptr; but the 'MEM <uint128_t> [(c_char * {ref-all})&arr2] = _7;' remains and causes later the link error: ld: error: undefined symbol: arr2.13 for the offload side. * * * The replacement is done via omp-offload.cc's pass_omp_target_link::execute. Here, gimple_regimplify_operands (gsi_stmt (gsi), &gsi); is then called for the MEMREF - which starts some regimplification, in particular, the following is then reached: gimplify.cc's gimplify_expr ... /* We arrive here through the various re-gimplifcation paths. */ case MEM_REF: /* First try re-folding the whole thing. */ tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p), TREE_OPERAND (*expr_p, 0), TREE_OPERAND (*expr_p, 1)); if (tmp) … (tmp == NULL) … break; } /* Avoid re-gimplifying the address operand if it is already in suitable form. Re-gimplifying would mark the address operand addressable. Always gimplify when not in SSA form as we still may have to gimplify decls with value-exprs. */ if (!gimplify_ctxp || !gimple_in_ssa_p (cfun) || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0))) { ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, is_gimple_mem_ref_addr, fb_rvalue); if (ret == GS_ERROR) break; } recalculate_side_effects (*expr_p); * * * Full 'debug_tree': <mem_ref 0x7ffff72edd98 type <integer_type 0x7ffff72e9bd0 unsigned TI size <integer_cst 0x7ffff7202798 constant 128> unit-size <integer_cst 0x7ffff72027b0 constant 16> user align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff720ba80 precision:128 min <integer_cst 0x7ffff72d8a20 0> max <integer_cst 0x7ffff72ed758 340282366920938463463374607431768211455>> arg:0 <addr_expr 0x7ffff72dcb20 type <pointer_type 0x7ffff72e9dc8 type <array_type 0x7ffff72e9540> public unsigned DI size <integer_cst 0x7ffff7202468 constant 64> unit-size <integer_cst 0x7ffff7202480 constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set -1 structural-equality> constant arg:0 <var_decl 0x7ffff72f2090 arr2 type <array_type 0x7ffff72e9540> addressable static nonlocal TI declare-target-link.f90:3:28 size <integer_cst 0x7ffff7202798 128> unit-size <integer_cst 0x7ffff72027b0 16> align:128 warn_if_not_align:0 context <function_decl 0x7ffff72ecf00 sub> attributes <tree_list 0x7ffff72ed578 purpose <identifier_node 0x7ffff72ed550 omp declare target link>> value-expr <mem_ref 0x7ffff72ed9d8 type <array_type 0x7ffff72e9540> arg:0 <var_decl 0x7ffff72f21b0 arr2$13$linkptr> arg:1 <integer_cst 0x7ffff72d8ac8 constant 0>>> declare-target-link.f90:29:24 start: declare-target-link.f90:29:24 finish: declare-target-link.f90:29:24> arg:1 <integer_cst 0x7ffff72d8b40 type <pointer_type 0x7ffff72e9d20> constant 0>>
Created attachment 58512 [details] WIP patch - shows the location but fails as DECL_P is not a is_gimple_stmt The attached patch handles MEM <uint128_t> [(c_char * {ref-all})&arr2] by changing &arr2 (= a ADDR_EXPR) to arr2$13$linkptr (= a VAR_DECL) However, as the result simplified to a VAR_DECL != is_gimple_stmt(), it fails as gimplify_expr doesn't handle this.
Patch: https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658737.html
The master branch has been updated by Tobias Burnus <burnus@gcc.gnu.org>: https://gcc.gnu.org/g:c99cdcab4f1c497a872cf552138fd8ea27e9a5eb commit r15-2472-gc99cdcab4f1c497a872cf552138fd8ea27e9a5eb Author: Tobias Burnus <tburnus@baylibre.com> Date: Thu Aug 1 09:06:32 2024 +0200 omp-offload.cc: Fix value-expr handling of 'declare target link' vars [PR115637] As the PR and included testcase shows, replacing 'arr2' by its value expression '*arr2$13$linkptr' failed for MEM <uint128_t> [(c_char * {ref-all})&arr2] which left 'arr2' in the code as unknown symbol. Now expand the value expression already in pass_omp_target_link::execute's process_link_var_op walk_gimple_stmt walk - and don't rely on gimple_regimplify_operands. PR middle-end/115637 gcc/ChangeLog: * gimplify.cc (gimplify_body): Fix macro name in the comment. * omp-offload.cc (find_link_var_op): Rename to ... (process_link_var_op): ... this. Replace value expr. (pass_omp_target_link::execute): Update walk_gimple_stmt call. libgomp/ChangeLog: * testsuite/libgomp.fortran/declare-target-link.f90: Uncomment now working code. Co-authored-by: Richard Biener <rguenther@suse.de
FIXED on mainline (GCC 15). * * * For remaining 'declare target link' issues, see: Follow-up/related issue are tracked elsewhere: * C: Nested functions + declare target link → PR 115574 * Fortran: COMMON block issues + declare target link → PR 115577