This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[PATCH] Fix gfortran.dg/forall_1.f90
On Tue, Jun 07, 2005 at 11:11:06AM -0400, Jakub Jelinek wrote:
> FYI, the bug is in the
> forall (i=1:15, j=1:10, a1(j)%k <= j)
> i2(i,j) = j + i*11
> end forall
>
> code. The temp array of logical4 (logical4 temp.26[150]; in my case,
> BTW, does it really have to be logical4, can't be some 8 bit type?)
> is computed correctly (150x .true.), but when used to see
> if i2(i,j) should be stored or not, it advances by 16 logical4s
> each time instead of 15, so in the last round it accesses 10 words
> after the end of the array.
Here is a fix. gfc_trans_forall_loop was emitting mi += 1 statement
for multi-dimensional loops for each control variable, so we ended up with:
mi.27 = 0;
j.25 = 1;
count.31 = 10;
<D924>:;
if (count.31 <= 0)
goto L.14;
i.24 = 1;
count.30 = 15;
<D925>:;
if (count.30 <= 0)
goto L.13;
mi.43 = mi.27;
D.926 = temp.26[mi.43];
if (D.926)
{
D.927 = (int8) i.24;
D.920 = (int8) j.25;
D.928 = D.920 * 15;
D.929 = D.927 + D.928;
D.930 = D.929 + -16;
D.931 = i.24 * 11;
D.932 = D.931 + j.25;
i2[D.930] = D.932;
}
i.24 = i.24 + 1;
mi.27 = mi.27 + 1; <==== addition in the innermost loop
count.30 = count.30 - 1;
goto <D925>;
L.13:;
j.25 = j.25 + 1;
mi.27 = mi.27 + 1; <==== addition in the outer loop
count.31 = count.31 - 1;
goto <D924>;
L.14:;
Of course we only want to increment it in the innermost loop which
contains the load of the mask. Here is a fix, tested with no check-f95
failures on x86_64-linux. Ok for HEAD and 4.0.2?
Alternatively, the increment could be moved to gfc_trans_nested_forall_loop
and body passed as stmtblock_t instead of tree. This change is shorter
though...
2005-06-07 Jakub Jelinek <jakub@redhat.com>
* trans-stmt.c (gfc_trans_forall_loop): Only increment maskindex
in the innermost loop.
--- gcc/fortran/trans-stmt.c.jj 2005-06-07 12:35:06.000000000 +0200
+++ gcc/fortran/trans-stmt.c 2005-06-07 20:14:35.000000000 +0200
@@ -1365,8 +1365,9 @@ gfc_trans_forall_loop (forall_info *fora
tmp = build2 (PLUS_EXPR, TREE_TYPE (var), var, step);
gfc_add_modify_expr (&block, var, tmp);
- /* Advance to the next mask element. */
- if (mask_flag)
+ /* Advance to the next mask element. Only do this for the
+ innermost loop. */
+ if (n == 0 && mask_flag)
{
mask = forall_tmp->mask;
maskindex = forall_tmp->maskindex;
Jakub