[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-28 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

Andrew Pinski  changed:

   What|Removed |Added

   Target Milestone|--- |13.0

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-28 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

anlauf at gcc dot gnu.org changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|ASSIGNED|RESOLVED

--- Comment #15 from anlauf at gcc dot gnu.org ---
Fixed on mainline for gcc-13.  Closing.

Thanks for the report!

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-28 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #14 from CVS Commits  ---
The master branch has been updated by Harald Anlauf :

https://gcc.gnu.org/g:07b9bcc1d1484f8f1c850ff14db678fb6b1e4d36

commit r13-4375-g07b9bcc1d1484f8f1c850ff14db678fb6b1e4d36
Author: Harald Anlauf 
Date:   Sun Nov 27 21:10:18 2022 +0100

Fortran: ICE with elemental and dummy argument with VALUE attribute
[PR107819]

gcc/fortran/ChangeLog:

PR fortran/107819
* trans-stmt.cc (gfc_conv_elemental_dependencies): In checking for
elemental dependencies, treat dummy argument with VALUE attribute
as implicitly having intent(in).

gcc/testsuite/ChangeLog:

PR fortran/107819
* gfortran.dg/elemental_dependency_7.f90: New test.

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-27 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

anlauf at gcc dot gnu.org changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |anlauf at gcc dot 
gnu.org

--- Comment #13 from anlauf at gcc dot gnu.org ---
Submitted: https://gcc.gnu.org/pipermail/fortran/2022-November/058556.html

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-26 Thread mikael at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #12 from Mikael Morin  ---
(In reply to anlauf from comment #11)
> Update: Steve Lionel thinks that no temporary is necessary, and testcase
> z1.f90
> is non-conforming:
> 
> https://community.intel.com/t5/Intel-Fortran-Compiler/ELEMENTAL-subroutine-
> and-dummy-with-VALUE-attribute/m-p/1432932
> 
> In this case the patch of comment#2 would be sufficient.

I was about to suggest to push the check_variable value change down into
gfc_check_fncall_dependency, to be more aggressive wrt temporary elimination.
But if the test is not conforming, let's throw all that away.

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-26 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #11 from anlauf at gcc dot gnu.org ---
Update: Steve Lionel thinks that no temporary is necessary, and testcase z1.f90
is non-conforming:

https://community.intel.com/t5/Intel-Fortran-Compiler/ELEMENTAL-subroutine-and-dummy-with-VALUE-attribute/m-p/1432932

In this case the patch of comment#2 would be sufficient.

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-25 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #10 from anlauf at gcc dot gnu.org ---
Created attachment 53968
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53968=edit
Revised patch

(In reply to Mikael Morin from comment #9)
> It seems the semantics when an argument has the value attribute is the same
> as the case ELEM_CHECK_VARIABLE in my previous comment.
> So forcing the value of the elemental argument to ELEM_CHECK_VARIABLE at
> some appropriate place could possibly work.

Many thanks for the explanations!

Looking at the involved code, the most simple solution I came up with is
attached.  It scans over the actual arguments associated with the dummies,
and when we find one with the VALUE attribute, we enforce the dependency
check.  It fixes the testcase and regtests fine.

I was struggling with the actual generated code, which is rather a temporary
for the arguments with INTENT(INOUT/OUT), but that should be functionally
equivalent.

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-24 Thread mikael at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #9 from Mikael Morin  ---
(In reply to anlauf from comment #7)
> 
> In the meantime, do you have an idea where to force the generation of a
> temporary?  I've been scrolling through gfc_conv_procedure_call to see
> if that might be the right place, but that's not a small function...

It seems the semantics when an argument has the value attribute is the same as
the case ELEM_CHECK_VARIABLE in my previous comment.
So forcing the value of the elemental argument to ELEM_CHECK_VARIABLE at some
appropriate place could possibly work.

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-24 Thread mikael at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #8 from Mikael Morin  ---
(In reply to anlauf from comment #3)
> Could need help by some expert on this...

I guess I qualify as expert.
Reading the code again after years, it is not exactly crystal clear...

Here is a dump of what I could gather about the gfc_check_fncall_dependency and
friends functions.


The different gfc_dep_check cases are the following:


ELEM_DONT_CHECK_VARIABLE:
This is the simple case of direct subroutine call.
As per the 15.5.2.13 I quoted above, this is invalid:
  call elem_sub(a(2:n), a(1:n-1))
while this isn't
  call elem_sub(a, a)

so we can always generate:
  do i = ...
call elem_sub(a(...), a(...))
  end do

without caring for temporaries


ELEM_CHECK_VARIABLE:
This is the case of multiple elemental procedures.
For example:
  call elem_sub(a, elem_func(a))

The semantics is like:
  tmp = elem_func(a)
  call elem_sub(a, tmp)

Here, elem_sub can write to a without modifying tmp, and we have to
preserve that.
We generate code like this:
  do i = ...
call elem_sub(tmp(i), elem_func(a(i)))
  end do
  a = tmp
and try to avoid the temporary tmp if possible.
we explore the second argument to elem_sub and look for the same variable
as the expression from the first one, and we generate a temporary
if we find it.  But there is no need if they are strictly the same
variable reference.


NOT_ELEMENTAL:
This is the case of the presence of transpose in the expression
For example, for elem_sub(var, elem_func(transpose(var))), the semantics is:
  tmp1 = transpose(var)
  tmp2 = elem_func(tmp1)
  call elem_sub(var, tmp2)

which we try to preserve, but with less temporaries.
We try to generate
  do i = ..., j = ...
call elem_sub(tmp(i,j), elem_func(var(j,i)))
  end do
  var = tmp

and try to avoid the temporary tmp if possible (it's not with this example).
We have to make sure that if the same variable appears in a subexpression
of the argument, a temporary is generated.
Contrary to the previous case, we have to generate the temporary
even if the variable references are strictly the same.

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-24 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #7 from anlauf at gcc dot gnu.org ---
(In reply to Mikael Morin from comment #6)
> (In reply to anlauf from comment #5)
> > Second, I stumbled over:
> > 
> > ! 15.5.2.3 Argument association
> > ! (4) A present dummy argument with the VALUE attribute becomes argument
> > ! associated with a definable anonymous data object whose initial value is
> > ! the value of the actual argument.
> > 
> Ouch! You're right, this makes the part I quoted above irrelevant.
> And it explicitly asks for a temporary.

I've asked Intel if they agree with this interpretation.

In the meantime, do you have an idea where to force the generation of a
temporary?  I've been scrolling through gfc_conv_procedure_call to see
if that might be the right place, but that's not a small function...

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-24 Thread mikael at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #6 from Mikael Morin  ---
(In reply to anlauf from comment #5)
> (In reply to Mikael Morin from comment #4)
> > But is it required to generate a temporary?
> > As I understand it, the code is invalid, and (correctly) diagnosed, so there
> > is nothing else to do.
> > It's invalid because of 15.5.2.13 Restrictions on entities associated with
> > dummy arguments:
> > (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 shall be referenced
> > only through that dummy argument unless (...)
> 
> Right.
> 
> I was confused by two observations.  First, NAG & Cray seem to generate
> temporaries, while Intel and NVidia don't and would agree with gfortran
> after the patch.
> 
> Second, I stumbled over:
> 
> ! 15.5.2.3 Argument association
> ! (4) A present dummy argument with the VALUE attribute becomes argument
> ! associated with a definable anonymous data object whose initial value is
> ! the value of the actual argument.
> 
Ouch! You're right, this makes the part I quoted above irrelevant.
And it explicitly asks for a temporary.

> So it boils down to what ELEMENTAL actually means in that context.  F2018:
> 
> 15.8.3 Elemental subroutine actual arguments
> 
> ! In a reference to an elemental subroutine, if the actual arguments
> ! corresponding to INTENT(OUT) and INTENT(INOUT) dummy arguments are
> ! arrays, the values of the elements, if any, of the results are the same
> ! as would be obtained if the subroutine had been applied separately, in
> ! array element order, to corresponding elements of each array actual
> ! argument.
> 
> So I read this that
> 
>call s (a(n), a)
> 
> is to be interpreted as
> 
>   do i = 1, size (a)
>  call s (a(n(i)), a(i))
>   end do
> 
> and this would actually be well-defined behavior... ;-)

With your quote from 15.5.2.3 above, it would be more like:
do i = 1, size(a)
  tmp(i) = a(n(i))
end do
do i = 1, size(a)
  call s(tmp(i), a(i))
end do

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-24 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #5 from anlauf at gcc dot gnu.org ---
(In reply to Mikael Morin from comment #4)
> But is it required to generate a temporary?
> As I understand it, the code is invalid, and (correctly) diagnosed, so there
> is nothing else to do.
> It's invalid because of 15.5.2.13 Restrictions on entities associated with
> dummy arguments:
> (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 shall be referenced
> only through that dummy argument unless (...)

Right.

I was confused by two observations.  First, NAG & Cray seem to generate
temporaries, while Intel and NVidia don't and would agree with gfortran
after the patch.

Second, I stumbled over:

! 15.5.2.3 Argument association
! (4) A present dummy argument with the VALUE attribute becomes argument
! associated with a definable anonymous data object whose initial value is
! the value of the actual argument.

So it boils down to what ELEMENTAL actually means in that context.  F2018:

15.8.3 Elemental subroutine actual arguments

! In a reference to an elemental subroutine, if the actual arguments
! corresponding to INTENT(OUT) and INTENT(INOUT) dummy arguments are
! arrays, the values of the elements, if any, of the results are the same
! as would be obtained if the subroutine had been applied separately, in
! array element order, to corresponding elements of each array actual
! argument.

So I read this that

   call s (a(n), a)

is to be interpreted as

  do i = 1, size (a)
 call s (a(n(i)), a(i))
  end do

and this would actually be well-defined behavior... ;-)

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-24 Thread mikael at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

Mikael Morin  changed:

   What|Removed |Added

 CC||mikael at gcc dot gnu.org

--- Comment #4 from Mikael Morin  ---
(In reply to anlauf from comment #3)
> But then no temporary is generated for a(n), which means we miss a
> corresponding check elsewhere.
> 
But is it required to generate a temporary?
As I understand it, the code is invalid, and (correctly) diagnosed, so there is
nothing else to do.
It's invalid because of 15.5.2.13 Restrictions on entities associated with
dummy arguments:
(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 shall be referenced only
through that dummy argument unless (...)

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-22 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #3 from anlauf at gcc dot gnu.org ---
(In reply to anlauf from comment #2)
> Potential patch:

This regtests ok.

However,

> Note that we get a (correct) warning for z1 after this fix:
> 
> pr107819-z1.f90:4:10-16:
> 
> 4 |   call s (a(n), a)
>   |  2 1
> Warning: INTENT(OUT) actual argument at (1) might interfere with actual
> argument at (2).

this comes from gfc_check_argument_var_dependency, where we see the INTENT(OUT)
argument a, we see a(n), and here

966   /* In case of elemental subroutines, there is no dependency
967  between two same-range array references.  */
968   if (gfc_ref_needs_temporary_p (expr->ref)
969   || gfc_check_dependency (var, expr, elemental ==
NOT_ELEMENTAL))

gfc_ref_needs_temporary_p (expr->ref) correctly returns true.
The comment sort of does not fit to what happens: the "range" is the same,
but n generates a permutation which is detected by gfc_ref_needs_temporary_p.
But then no temporary is generated for a(n), which means we miss a
corresponding check elsewhere.

Could need help by some expert on this...

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-22 Thread anlauf at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

anlauf at gcc dot gnu.org changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2022-11-22
   Keywords||ice-on-invalid-code,
   ||ice-on-valid-code
 Ever confirmed|0   |1
 CC||anlauf at gcc dot gnu.org

--- Comment #2 from anlauf at gcc dot gnu.org ---
Confirmed.

Potential patch:

diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index fd6d294147e..b288f1f9050 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -264,6 +264,7 @@ gfc_conv_elemental_dependencies (gfc_se * se, gfc_se *
loopse,
   if (e->expr_type == EXPR_VARIABLE
&& e->rank && fsym
&& fsym->attr.intent != INTENT_IN
+   && !fsym->attr.value
&& gfc_check_fncall_dependency (e, fsym->attr.intent,
sym, arg0, check_variable))
{

Note that we get a (correct) warning for z1 after this fix:

pr107819-z1.f90:4:10-16:

4 |   call s (a(n), a)
  |  2 1
Warning: INTENT(OUT) actual argument at (1) might interfere with actual
argument at (2).

[Bug fortran/107819] ICE in gfc_check_argument_var_dependency, at fortran/dependency.cc:978

2022-11-22 Thread gscfq--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #1 from G. Steinmetz  ---

Works here with explicitly enforced evaluation (a(n)) :


$ cat z3.f90
program p
   integer :: a(4) = [-1, -2, -3, -4]
   integer :: n(4) = [4, 2, 1, 3]
   call s ((a(n)), a)
   print *, a
contains
   elemental subroutine s (x, y)
  integer, value :: x
  integer, intent(out) :: y
  y = x
   end
end


$ cat z8.f90
program p
   implicit none
   integer, parameter :: m = 99
   integer :: i
   integer :: a(m) = [(-i,i=1,m)]
   call s ((a(m:1:-1)), a)
   print '(10i6)', a
contains
   elemental subroutine s (x, y)
  integer, value :: x
  integer, intent(out) :: y
  y = x
   end
end


$ cat z9.f90
program p
   implicit none
   integer, parameter :: m = 99
   integer :: i
   integer :: a(m) = [(-i,i=1,m)]
   integer :: n(m) = [(i,i=m,1,-1)]
   call s ([a(n)], a)
   print '(10i6)', a
contains
   elemental subroutine s (x, y)
  integer, value :: x
  integer, intent(out) :: y
  y = x
   end
end


$ gfortran-13-20221120 z3.f90 && ./a.out
  -4  -2  -1  -3
$