Re: [PATCH, Fortran] Fix setting of array lower bound for named arrays

2021-11-30 Thread Toon Moene

On 11/30/21 8:54 PM, Harald Anlauf via Fortran wrote:


Hi Tobias,



You seem to be quite convinced with your interpretation,
while I am simply confused.


If both compiler developers are confused, and actual compiler 
implementations differ in their outcomes of the test case, IMNSHO it is 
time to ask the Fortran Standardization Committee for an interpretation 
(of the standard's text).


Kind regards,

--
Toon Moene - e-mail: t...@moene.org - phone: +31 346 214290
Saturnushof 14, 3738 XG  Maartensdijk, The Netherlands


Re: [PATCH, Fortran] Fix setting of array lower bound for named arrays

2021-11-30 Thread Harald Anlauf via Gcc-patches

Hi Tobias,

Am 30.11.21 um 18:24 schrieb Tobias Burnus:

On 29.11.21 22:11, Harald Anlauf wrote:


"A whole array is a named array or a structure component whose final
part-ref is an array component name; no subscript list is appended."

I think in "h(3)" there is not really a named array – thus I read it as
if the "Otherwise ... result value is 1" applies.


If you read on in the standard:

"The appearance of a whole array variable in an executable construct
specifies all the elements of the array ..."

which might make you/makes me think that the sentence before that one
could need an official interpretation...


I am not sure whether I understand what part of the spec you wonder
about. (I mean besides that 'variable' can also mean referencing a
data-pointer-returning function.)


strictly speaking you're now talking about the text for LBOUND,
and your quote is not from the standard section about the ALLOCATE
statement.  And there are several places in the standard document
where there is an explicit reference to LBOUND when talking about
what the bounds should be.  This is why I am unhappy with the text
about ALLOCATE, not about LBOUND.


Question: What do NAG/flang/... report for lbound(h(3)) - also [3] – or
[1] as gfortran?


I've submitted a reduced example to the Intel Fortran Forum:
https://community.intel.com/t5/Intel-Fortran-Compiler/Allocate-with-SOURCE-and-bounds/m-p/1339992#M158535



There are good chances that Steve Lionel reads and comments on it.


So far only "FortranFan" has replied – and he comes to the same
conclusion as my reading, albeit without referring to the standard.


You seem to be quite convinced with your interpretation,
while I am simply confused.

So go ahead and apply to mainline.  Let's see if we learn more.
I do hope I will.

Harald


Tobias

-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201,
80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer:
Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München;
Registergericht München, HRB 106955





Re: [PATCH, Fortran] Fix setting of array lower bound for named arrays

2021-11-30 Thread Tobias Burnus

On 29.11.21 22:11, Harald Anlauf wrote:


"A whole array is a named array or a structure component whose final
part-ref is an array component name; no subscript list is appended."

I think in "h(3)" there is not really a named array – thus I read it as
if the "Otherwise ... result value is 1" applies.


If you read on in the standard:

"The appearance of a whole array variable in an executable construct
specifies all the elements of the array ..."

which might make you/makes me think that the sentence before that one
could need an official interpretation...


I am not sure whether I understand what part of the spec you wonder
about. (I mean besides that 'variable' can also mean referencing a
data-pointer-returning function.)

Question: What do NAG/flang/... report for lbound(h(3)) - also [3] – or
[1] as gfortran?


I've submitted a reduced example to the Intel Fortran Forum:
https://community.intel.com/t5/Intel-Fortran-Compiler/Allocate-with-SOURCE-and-bounds/m-p/1339992#M158535


There are good chances that Steve Lionel reads and comments on it.


So far only "FortranFan" has replied – and he comes to the same
conclusion as my reading, albeit without referring to the standard.

Tobias

-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955


Re: [PATCH, Fortran] Fix setting of array lower bound for named arrays

2021-11-29 Thread Harald Anlauf via Gcc-patches

Hi Tobias, all,

Am 29.11.21 um 21:56 schrieb Tobias Burnus:

The problem is that the standard does not really state what the bounds
are :-(


I sort of expected that comment...


Usually, it ends up referring to LBOUND (with wordings like "each lower
bound equal to the corresponding element of LBOUND (expr)") – albeit not
in this case.

Assuming that holds, the question is what's lbound(h(3))? gfortran gives
[1] for that one. What does NAG yield?

For lbound(h(3),dim=1), the standard has:

"If DIM is present, ARRAY is a whole array, and either ARRAY is an
assumed-size array of rank DIM or dimension DIM of ARRAY has nonzero
extent, the result has a value equal to the lower bound for subscript
DIM of ARRAY. Otherwise, if DIM is present, the result value is 1."

Thus, the question is whether "h(3)" is a 'whole array' or not. That reads:


F2018: 9.5.2 Whole arrays


"A whole array is a named array or a structure component whose final
part-ref is an array component name; no subscript list is appended."

I think in "h(3)" there is not really a named array – thus I read it as
if the "Otherwise ... result value is 1" applies.


If you read on in the standard:

"The appearance of a whole array variable in an executable construct
specifies all the elements of the array ..."

which might make you/makes me think that the sentence before that one
could need an official interpretation...

I've submitted a reduced example to the Intel Fortran Forum:

https://community.intel.com/t5/Intel-Fortran-Compiler/Allocate-with-SOURCE-and-bounds/m-p/1339992#M158535

There are good chances that Steve Lionel reads and comments on it.

You're invited to add to that thread!

Harald


Tobias

-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201,
80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer:
Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München;
Registergericht München, HRB 106955





Re: [PATCH, Fortran] Fix setting of array lower bound for named arrays

2021-11-29 Thread Tobias Burnus

Hi Harald, hi Chung-Lin,

On 29.11.21 21:21, Harald Anlauf wrote:

I think you need to check the following:

 allocate(c, source=h(3))
 write(*,*) lbound(c,1), ubound(c,1) ! prints 1 3
...
 pure function h(i) result(r)
  integer, value, intent(in) :: i
  integer, allocatable :: r(:)
  allocate(r(3:5))
  r = [1,2,3]
 end function h

This used to print 3 5, which is also what e.g. NAG, Nvidia, flang do.
Intel prints 1 3, so it agrees with you.

Hmm, usually NAG is right ...

The Fortran standard has:
9.7.1.2  Execution of an ALLOCATE statement

(6) When an ALLOCATE statement is executed for an array with no
allocate-shape-spec-list, the bounds of source-expr determine the
bounds of the array. Subsequent changes to the bounds of source-expr
do not affect the array bounds.


The problem is that the standard does not really state what the bounds
are :-(

Usually, it ends up referring to LBOUND (with wordings like "each lower
bound equal to the corresponding element of LBOUND (expr)") – albeit not
in this case.

Assuming that holds, the question is what's lbound(h(3))? gfortran gives
[1] for that one. What does NAG yield?

For lbound(h(3),dim=1), the standard has:

"If DIM is present, ARRAY is a whole array, and either ARRAY is an
assumed-size array of rank DIM or dimension DIM of ARRAY has nonzero
extent, the result has a value equal to the lower bound for subscript
DIM of ARRAY. Otherwise, if DIM is present, the result value is 1."

Thus, the question is whether "h(3)" is a 'whole array' or not. That reads:

"A whole array is a named array or a structure component whose final
part-ref is an array component name; no subscript list is appended."

I think in "h(3)" there is not really a named array – thus I read it as
if the "Otherwise ... result value is 1" applies.

Tobias

-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955


Re: [PATCH, Fortran] Fix setting of array lower bound for named arrays

2021-11-29 Thread Harald Anlauf via Gcc-patches

Hi Chung-Lin,

Am 29.11.21 um 15:25 schrieb Chung-Lin Tang:

This patch by Tobias, fixes a case of setting array low-bounds, found
for particular uses of SOURCE=/MOLD=.

For example:
program A_M
   implicit none
   real, dimension (:), allocatable :: A, B
   allocate (A(0:5))
   call Init (A)
contains
   subroutine Init ( A )
     real, dimension ( 0 : ), intent ( in ) :: A
     integer, dimension ( 1 ) :: lb_B

     allocate (B, mold = A)
     ...
     lb_B = lbound (B, dim=1)   ! Error: lb_B assigned 1, instead of 0
like lower-bound of A.

Referencing the Fortran standard:

"16.9.109 LBOUND (ARRAY [, DIM, KIND])"
states:
"If DIM is present, ARRAY is a whole array, and either ARRAY is
  an assumed-size array of rank DIM or dimension DIM of ARRAY has
  nonzero extent, the result has a value equal to the lower bound
  for subscript DIM of ARRAY. Otherwise, if DIM is present, the
  result value is 1."

And on what is a "whole array":

"9.5.2 Whole arrays"
"A whole array is a named array or a structure component ..."

The attached patch adjusts the relevant part in gfc_trans_allocate() to
only set
e3_has_nodescriptor only for non-named arrays.

Tobias has tested this once, and I've tested this patch as well on our
complete set of
testsuites (which usually serves for OpenMP related stuff). Everything
appears well with no regressions.

Is this okay for trunk?


I think you need to check the following:

 allocate(c, source=h(3))
 write(*,*) lbound(c,1), ubound(c,1) ! prints 1 3

...

 pure function h(i) result(r)
  integer, value, intent(in) :: i
  integer, allocatable :: r(:)
  allocate(r(3:5))
  r = [1,2,3]
 end function h

This used to print 3 5, which is also what e.g. NAG, Nvidia, flang do.
Intel prints 1 3, so it agrees with you.

The Fortran standard has:

9.7.1.2  Execution of an ALLOCATE statement

(6) When an ALLOCATE statement is executed for an array with no
allocate-shape-spec-list, the bounds of source-expr determine the
bounds of the array. Subsequent changes to the bounds of source-expr
do not affect the array bounds.

Please re-check with Tobias.

Thanks,
Harald


Thanks,
Chung-Lin

2021-11-29  Tobias Burnus  

gcc/fortran/ChangeLog:

 * trans-stmt.c (gfc_trans_allocate): Set e3_has_nodescriptor to true
 only for non-named arrays.

gcc/testsuite/ChangeLog:

 * gfortran.dg/allocate_with_source_26.f90: Adjust testcase.
 * gfortran.dg/allocate_with_mold_4.f90: New testcase.




[PATCH, Fortran] Fix setting of array lower bound for named arrays

2021-11-29 Thread Chung-Lin Tang

This patch by Tobias, fixes a case of setting array low-bounds, found
for particular uses of SOURCE=/MOLD=.

For example:
program A_M
  implicit none
  real, dimension (:), allocatable :: A, B
  allocate (A(0:5))
  call Init (A)
contains
  subroutine Init ( A )
real, dimension ( 0 : ), intent ( in ) :: A
integer, dimension ( 1 ) :: lb_B

allocate (B, mold = A)
...
lb_B = lbound (B, dim=1)   ! Error: lb_B assigned 1, instead of 0 like 
lower-bound of A.

Referencing the Fortran standard:

"16.9.109 LBOUND (ARRAY [, DIM, KIND])"
states:
"If DIM is present, ARRAY is a whole array, and either ARRAY is
 an assumed-size array of rank DIM or dimension DIM of ARRAY has
 nonzero extent, the result has a value equal to the lower bound
 for subscript DIM of ARRAY. Otherwise, if DIM is present, the
 result value is 1."

And on what is a "whole array":

"9.5.2 Whole arrays"
"A whole array is a named array or a structure component ..."

The attached patch adjusts the relevant part in gfc_trans_allocate() to only set
e3_has_nodescriptor only for non-named arrays.

Tobias has tested this once, and I've tested this patch as well on our complete 
set of
testsuites (which usually serves for OpenMP related stuff). Everything appears 
well with no regressions.

Is this okay for trunk?

Thanks,
Chung-Lin

2021-11-29  Tobias Burnus  

gcc/fortran/ChangeLog:

* trans-stmt.c (gfc_trans_allocate): Set e3_has_nodescriptor to true
only for non-named arrays.

gcc/testsuite/ChangeLog:

* gfortran.dg/allocate_with_source_26.f90: Adjust testcase.
* gfortran.dg/allocate_with_mold_4.f90: New testcase.diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index bdf7957..982e1e0 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -6660,16 +6660,13 @@ gfc_trans_allocate (gfc_code * code)
   else
e3rhs = gfc_copy_expr (code->expr3);
 
-  // We need to propagate the bounds of the expr3 for source=/mold=;
-  // however, for nondescriptor arrays, we use internally a lower bound
-  // of zero instead of one, which needs to be corrected for the allocate 
obj
-  if (e3_is == E3_DESC)
-   {
- symbol_attribute attr = gfc_expr_attr (code->expr3);
- if (code->expr3->expr_type == EXPR_ARRAY ||
- (!attr.allocatable && !attr.pointer))
-   e3_has_nodescriptor = true;
-   }
+  // We need to propagate the bounds of the expr3 for source=/mold=.
+  // However, for non-named arrays, the lbound has to be 1 and neither the
+  // bound used inside the called function even when returning an
+  // allocatable/pointer nor the zero used internally.
+  if (e3_is == E3_DESC
+ && code->expr3->expr_type != EXPR_VARIABLE)
+   e3_has_nodescriptor = true;
 }
 
   /* Loop over all objects to allocate.  */
diff --git a/gcc/testsuite/gfortran.dg/allocate_with_mold_4.f90 
b/gcc/testsuite/gfortran.dg/allocate_with_mold_4.f90
new file mode 100644
index 000..d545fe1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/allocate_with_mold_4.f90
@@ -0,0 +1,24 @@
+program A_M
+  implicit none
+  real, parameter :: C(5:10) = 5.0
+  real, dimension (:), allocatable :: A, B
+  allocate (A(6))
+  call Init (A)
+contains
+  subroutine Init ( A )
+real, dimension ( -1 : ), intent ( in ) :: A
+integer, dimension ( 1 ) :: lb_B
+
+allocate (B, mold = A)
+if (any (lbound (B) /= lbound (A))) stop 1
+if (any (ubound (B) /= ubound (A))) stop 2
+if (any (shape (B) /= shape (A))) stop 3
+if (size (B) /= size (A)) stop 4
+deallocate (B)
+allocate (B, mold = C)
+if (any (lbound (B) /= lbound (C))) stop 5
+if (any (ubound (B) /= ubound (C))) stop 6
+if (any (shape (B) /= shape (C))) stop 7
+if (size (B) /= size (C)) stop 8
+end
+end 
diff --git a/gcc/testsuite/gfortran.dg/allocate_with_source_26.f90 
b/gcc/testsuite/gfortran.dg/allocate_with_source_26.f90
index 28f24fc..323c8a3 100644
--- a/gcc/testsuite/gfortran.dg/allocate_with_source_26.f90
+++ b/gcc/testsuite/gfortran.dg/allocate_with_source_26.f90
@@ -34,23 +34,23 @@ program p
  if (lbound(p1, 1) /= 3 .or. ubound(p1, 1) /= 4 &
  .or. lbound(p2, 1) /= 3 .or. ubound(p2, 1) /= 4 &
  .or. lbound(p3, 1) /= 1 .or. ubound(p3, 1) /= 2 &
- .or. lbound(p4, 1) /= 7 .or. ubound(p4, 1) /= 8 &
+ .or. lbound(p4, 1) /= 1 .or. ubound(p4, 1) /= 2 &
  .or. p1(3)%i /= 43 .or. p1(4)%i /= 56 &
  .or. p2(3)%i /= 43 .or. p2(4)%i /= 56 &
  .or. p3(1)%i /= 43 .or. p3(2)%i /= 56 &
- .or. p4(7)%i /= 11 .or. p4(8)%i /= 12) then
+ .or. p4(1)%i /= 11 .or. p4(2)%i /= 12) then
call abort()
  endif
 
  !write(*,*) lbound(a,1), ubound(a,1) ! prints 1 3
  !write(*,*) lbound(b,1), ubound(b,1) ! prints 1 3
- !write(*,*) lbound(c,1), ubound(c,1) ! prints 3 5
+ !write(*,*) lbound(c,1), ubound(c,1) ! prints 1 3
  !write(*,*) lbound(d,1), ubound(d,1) ! prints 1 5
  !write(*,*) lbound(e,1), ubound(e,1) ! prints 1 6