From: Tobias Burnus Date: Fri, 12 Oct 2018 18:18:13 +0000 (+0200) Subject: Fix off-by-one issue with inline matmul X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=47b92d22d3aea04ce6a936c768953dd0406f41c2;p=gcc.git Fix off-by-one issue with inline matmul PR fortran/87597 * expr.c (gfc_simplify_expr): Avoid simplifying the 'array' argument to lbound/ubound/lcobound/ ucobound. PR fortran/87597 * gfortran.dg/inline_matmul_24.f90: New. From-SVN: r265126 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 21813638bf3..4ee065a19a0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2018-10-12 Tobias Burnus + + PR fortran/87597 + * expr.c (gfc_simplify_expr): Avoid simplifying + the 'array' argument to lbound/ubound/lcobound/ + ucobound. + 2018-10-12 Tobias Burnus PR fortran/58787 diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 1cfda5fbfed..ca6f95d9d8e 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -1937,7 +1937,20 @@ gfc_simplify_expr (gfc_expr *p, int type) break; case EXPR_FUNCTION: - for (ap = p->value.function.actual; ap; ap = ap->next) + // For array-bound functions, we don't need to optimize + // the 'array' argument. In particular, if the argument + // is a PARAMETER, simplifying might convert an EXPR_VARIABLE + // into an EXPR_ARRAY; the latter has lbound = 1, the former + // can have any lbound. + ap = p->value.function.actual; + if (p->value.function.isym && + (p->value.function.isym->id == GFC_ISYM_LBOUND + || p->value.function.isym->id == GFC_ISYM_UBOUND + || p->value.function.isym->id == GFC_ISYM_LCOBOUND + || p->value.function.isym->id == GFC_ISYM_UCOBOUND)) + ap = ap->next; + + for ( ; ap; ap = ap->next) if (!gfc_simplify_expr (ap->expr, type)) return false; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4991c2ef54f..3604fe63137 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-10-12 Tobias Burnus + + PR fortran/87597 + * gfortran.dg/inline_matmul_24.f90: New. + 2018-10-12 Tobias Burnus PR fortran/58787 diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_24.f90 b/gcc/testsuite/gfortran.dg/inline_matmul_24.f90 new file mode 100644 index 00000000000..067f6daf200 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_matmul_24.f90 @@ -0,0 +1,42 @@ +! { dg-do run } +! { dg-options "-ffrontend-optimize -fdump-tree-original" } +! +! PR fortran/87597 +! +! Contributed by gallmeister +! +! Before, for the inlined matmul, +! gamma5 was converted to an EXPR_ARRAY with lbound = 1 +! instead of the lbound = 0 as declared; leading to +! an off-by-one problem. +! +program testMATMUL + implicit none + complex, dimension(0:3,0:3), parameter :: gamma5 = reshape((/ 0., 0., 1., 0., & + 0., 0., 0., 1., & + 1., 0., 0., 0., & + 0., 1., 0., 0. /),(/4,4/)) + complex, dimension(0:3,0:3) :: A, B, D + integer :: i + + A = 0.0 + do i=0,3 + A(i,i) = i*1.0 + end do + + B = cmplx(7,-9) + B = matmul(A,gamma5) + + D = reshape([0, 0, 2, 0, & + 0, 0, 0, 3, & + 0, 0, 0, 0, & + 0, 1, 0, 0], [4, 4]) + write(*,*) B(0,:) + write(*,*) B(1,:) + write(*,*) B(2,:) + write(*,*) B(3,:) + if (any(B /= D)) then + call abort() + end if +end program testMATMUL +! { dg-final { scan-tree-dump-times "gamma5\[__var_1_do \\* 4 \\+ __var_2_do\]" 1 "optimized" } }