From: Tobias Burnus on
Hi all,

I have an alias question regarding argument association.

I think the relevant part of the standard is "12.5.2.13 Restrictions on
entities associated with dummy arguments" (Fortran 2008, FDIS); in
Fortran 2003 it is 12.4.1.7 and in Fortran 95 it is 12.4.1.6. However,
there might be other relevant parts, which I have missed.


My question is whether the following program is valid. I think with
"target :: arr" (variant 1) it is, but the question is: Is it valid without?


If it is not valid, I assume that a conforming compiler could optimize
away the if-condition with the stop (variant 2). As I think it would
seriously hamper the optimization by the compiler, I hope that the
program is invalid. But currently, I do not see why. One possibility,
which I have not fully thought about is that it becomes invalid as for
"call bar(arr)" the actual argument is not a target, but I currently do
how this will propagate to foobar to make the program invalid.

If the program is valid, I expect the output "1 1 2" - and the same for
variant 1. For variant 2 I expect that the program's execution ends with
the STOP statement.


Quote from the standard (F2008, FDIS):
---------------------------
"While an entity is associated with a dummy argument, the following
restrictions hold. [...]

(3) Action that affects the value of the entity or any subobject of it
shall be taken only through the dummy argument unless [...]
(b) the dummy argument has the TARGET attribute, the dummy argument does
not have INTENT(IN), the dummy argument is a scalar object or an
assumed-shape array without the CONTIGUOUS attribute, and the actual
argument is a target other than an array section with a vector subscript.

(4) If the value of the entity or any subobject of it is affected
through the dummy argument, then at any time during the invocation and
execution of the procedure, either before or after the definition, it
may be referenced only through that dummy argument unless
[same subitems as for (3)]
---------------------------


The program:

MODULE m
IMPLICIT NONE
INTEGER :: arr(3) ! no target
! Variant 1:
! TARGET :: arr
CONTAINS
SUBROUTINE foobar (arg)
INTEGER, TARGET :: arg(:)
! Variant 2:
! arr(1) = 5
! arg(1) = 6
! if (arr(1) /= 5) stop 'to alias or not to alias'
! End Variant 2
arr(2:3) = arg(1:2)
END SUBROUTINE foobar
END MODULE m

PROGRAM main
USE m
IMPLICIT NONE
arr = (/ 1, 2, 3 /)
CALL bar(arr)
PRINT *, arr
contains
subroutine bar(x)
INTEGER, TARGET :: x(3) ! Target
CALL foobar (x)
PRINT *, x
end subroutine bar
END PROGRAM main


Tobias
From: glen herrmannsfeldt on
Tobias Burnus <burnus(a)net-b.de> wrote:

> I have an alias question regarding argument association.

> I think the relevant part of the standard is "12.5.2.13 Restrictions on
> entities associated with dummy arguments" (Fortran 2008, FDIS); in
> Fortran 2003 it is 12.4.1.7 and in Fortran 95 it is 12.4.1.6. However,
> there might be other relevant parts, which I have missed.

> My question is whether the following program is valid. I think with
> "target :: arr" (variant 1) it is, but the question is: Is it valid without?
(big snip, including program code)

One of the reason for the aliasing rules is that Fortran allows for
either call by reference or call by value result (also known as
copy-in/copy-out), and aliasing can fail for that reason.

I believe that your program, even with the TARGET attribute,
fails in the case of call by value result. I am not so sure
that I can connect that to the rules that you posted, though.

-- glen
From: Tobias Burnus on
glen herrmannsfeldt wrote:
> Tobias Burnus <burnus(a)net-b.de> wrote:
>> My question is whether the following program is valid. I think with
>> "target :: arr" (variant 1) it is, but the question is: Is it valid without?
> (big snip, including program code)
>
> One of the reason for the aliasing rules is that Fortran allows for
> either call by reference or call by value result (also known as
> copy-in/copy-out), and aliasing can fail for that reason.

There is no copy-in/copy-out in this case - or at least: The
implementation works such that a pointer associated in the procedure
remains associated after one returns in the caller. Cf. "12.5.2.4
Ordinary dummy variables" in Fortran 2008.

Actually, that's the reason that only assumed-shape arrays are allowed
and the contiguous attribute is disallowed in Section 12.5.2.13. The
above mentioned Section 12.5.2.4 states in Paragraph 9:

"If the dummy argument has the TARGET attribute, does not have the VALUE
attribute, and either the effective argument is simply contiguous or the
dummy argument is a scalar or an assumed-shape array that does not have
the CONTIGUOUS attribute, and the effective argument has the TARGET
attribute but is not a coindexed object or an array section with a
vector subscript then
* any pointers associated with the effective argument become associated
with the corresponding dummy argument on invocation of the procedure, and
* when execution of the procedure completes, any pointers that do not
become undefined (16.5.2.5) and are associated with the dummy argument
remain associated with the effective argument."


> I believe that your program, even with the TARGET attribute,
> fails in the case of call by value result.

I disagree.

Tobias
From: glen herrmannsfeldt on
Tobias Burnus <burnus(a)net-b.de> wrote:

> I have an alias question regarding argument association.

> I think the relevant part of the standard is "12.5.2.13 Restrictions on
> entities associated with dummy arguments" (Fortran 2008, FDIS); in
> Fortran 2003 it is 12.4.1.7 and in Fortran 95 it is 12.4.1.6. However,
> there might be other relevant parts, which I have missed.
(snip)
(with arr and arg alias associated)

> arr(2:3) = arg(1:2)

In addition to the previous comments, note that Fortran requires
array assignment to behave as if the entire right side is evaluated
before the left side is changed. If the compiler can't be sure that
there is no aliasing, a temporary array will be required in this case.

Maybe that is part of the question you are asking, but I thought
it worth mentioning.

As far as I know, in the majority of array assignment cases the
compiler can determine that there is no aliasing and does the
assignment element by element. In many cases, pointers are an
indication to the compiler that legal aliasing might occur, and
the compiler should take that into account.

-- glen

From: Tobias Burnus on
glen herrmannsfeldt wrote:
> Tobias Burnus <burnus(a)net-b.de> wrote:
>> I have an alias question regarding argument association.
>
>> arr(2:3) = arg(1:2)
>
> In addition to the previous comments, note that Fortran requires
> array assignment to behave as if the entire right side is evaluated
> before the left side is changed. If the compiler can't be sure that
> there is no aliasing, a temporary array will be required in this case.

Exactly that's my problem: I think I have found a loop hole in the
standard, which makes it impossible to assume that a variable does not
alias - at least if in the procedure a dummy with the TARGET or POINTER
attribute exists (or is available via host association). [If one takes
the type into account, this reduces a bit, but still a huge number of
optimizations are no longer possible.]

At least I have still the feeling that the original program is valid and
none of the 7 compilers I have tried manages to give the correct result.
One does so, if one compiles everything in one file, but it also fails
(except with -O0) if one places the code in two files.

Tobias