This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, fortran] PR64952 - Missing temporary in assignment from elemental function


Dear All,

This came up at
https://groups.google.com/forum/#!topic/comp.lang.fortran/TvVY5j3GPmg

gfortran produces wrong result from:

PROGRAM Main
    INTEGER :: i, index(5) = (/ (i, i = 1,5) /)
    REAL :: array(5) = (/ (i+0.0, i = 1,5) /)
    array = Fred(index,array)
    PRINT *, array
CONTAINS
    ELEMENTAL FUNCTION Fred (n, x)
        REAL :: Fred
        INTEGER, INTENT(IN) :: n
        REAL, INTENT(IN) :: x
        ! In general, this would be in an external procedure
        Fred = x+SUM(array(:n-1))+SUM(array(n+1:))
     END FUNCTION Fred
END PROGRAM Main

outputs
15.0000000       29.0000000       56.0000000       109.000000
214.000000
when result should be
5*15.0

A temporary should be produced for array = Fred(index, array). See the
clf thread for the reasoning.

In a nutshell, the reason is:
    The execution of the assignment shall have the same effect as
    if the evaluation of expr and the evaluation of all expressions
    in variable occurred before any portion of the variable is
    defined by the assignment. The evaluation of expressions within
    variable shall neither affect nor be affected by the evaluation
    of expr.

Clearly, the above code violates this requirement because of the
references to 'array' in 'Fred'. I think that we will have to provide
an attribute that marks up array valued elemental functions that have
any external array references and provide a temporary for assignment
from one of these. Clearly something less brutal could be done, such
as attaching a list of external arrays (to the elemental function,
that is) to the symbol of the elemental function and comparing them
with the lhs of an assignment. However, this works and has no
perceivable effect on Polyhedron timings.

I will change the name of the flags to potentially_aliasing.

Bootstrapped and regtested on FC21/x86_64 - OK for trunk?

Paul

2015-02-08  Paul Thomas  <pault@gcc.gnu.org>

    PR fortran/64952
    * gfortran.h : Add 'potentially_aliased' field to symbol_attr.
    * trans.h : Add 'potentially_aliased' field to gfc_ss_info.
    * resolve.c (resolve_variable): Mark elemental function symbol
    as 'potentially_aliased' if it has an array reference from
    outside its own namespace.
    * trans-array.c (gfc_conv_resolve_dependencies): If any ss is
    marked as 'potentially_aliased' generate a temporary.
    (gfc_walk_function_expr): If the function is marked as
    'potentially_aliased', likewise mark the head gfc_ss.

2015-02-08  Paul Thomas  <pault@gcc.gnu.org>

    PR fortran/64952
    * gfortran.dg/finalize_28.f90: New test

Attachment: submit.diff
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]