https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113377

--- Comment #2 from anlauf at gcc dot gnu.org ---
(In reply to Mikael Morin from comment #1)
> (In reply to anlauf from comment #0)
> > The dump-tree suggests that the scalarizer sees the loop invariant j,
> > unconditionally dereferences it outside the loop,
> 
> Note that the copy to the variable before the loop does NOT dereference the
> pointer.

You are right: I was mistaken as I was looking at the code generated for
PR67277, especially at testcase gfortran.dg/ishftc_optional_size_1.f90,
function ishftc4_ref_4, where the scalarization deferences the optional
argument size_,

    D.4389 = *size_;

outside of the loop.

> This case is explicitly supported by the scalarizer, see
> gfc_scalar_elemental_arg_saved_as_reference (and
> gfc_walk_elemental_function_args for the initialization of the
> can_be_null_ref field).

I'll need to have a closer look here.

Note that adding a scalar call in function one:

    r(1) = two (i(1), j)

generates sane code:

  *((integer(kind=4) *) __result.0 + (sizetype) ((offset.1 + NON_LVALUE_EXPR
<stride.0>) * 4)) = two (&(*i)[0], j != 0B ? *j : 0, j != 0B);

> Normally this is sufficient to support optional dummies (there is also
> additional support for class wrappers in gfc_conv_procedure_call), except if
> value comes into play.
> 
> > generates code that
> > unconditionally dereferences j in the invocation of two, and uses a
> > wrong interface:
> These are the topics to investigate.
> I suppose we need to duplicate (or factor) the code for optional, value
> dummies that was added for non-elemental procedures in
> gfc_conv_procedure_call.

Probably yes.

There is another observation: using the value attribute for j also in one,
the scalar call from above becomes a straight

  *((integer(kind=4) *) __result.0 + (sizetype) ((offset.1 + NON_LVALUE_EXPR
<stride.0>) * 4)) = two (&(*i)[0], j, .j);

while the scalarizer produces:

    integer(kind=4) * D.4340;
...
    D.4340 = &j;
...
          *((integer(kind=4) *) __result.0 + (sizetype) ((S.3 * D.4342 +
D.4339) * 4)) = two (&(*i)[S.3 + -1], *D.4340);

which looks more complicated (besides being wrong...)

Reply via email to