https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115637
Bug ID: 115637 Summary: gimple_regimplify_operands doesn't handle VALUE_EXPR inside a MEM_REF / OpenMP declare target link Product: gcc Version: 15.0 Status: UNCONFIRMED Keywords: openmp, wrong-code Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: burnus at gcc dot gnu.org CC: jakub at gcc dot gnu.org Target Milestone: --- Created attachment 58511 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58511&action=edit 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>>