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>>

Reply via email to