From 40e1ed26774b7b6c24d166489a715aa75843ab36 Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Thu, 25 Jul 2019 16:24:00 +0000 Subject: [PATCH] re PR fortran/65819 (overzealous checking in gfc_check_dependency for identical=true) 2019-07-25 Thomas Koenig PR fortran/65819 * dependency.h (gfc_dep_resovler): Add optional argument identical. * dependency.c (gfc_check_dependency): Do not alway return 1 if the symbol is the same. Pass on identical to gfc_dep_resolver. (gfc_check_element_vs_element): Whitespace fix. (gfc_dep_resolver): Adjust comment for function. If identical is true, return 1 if any overlap has been found. 2019-07-25 Thomas Koenig PR fortran/65819 * gfortran.dg/dependency_54.f90: New test. From-SVN: r273807 --- gcc/fortran/ChangeLog | 20 ++++++++--- gcc/fortran/dependency.c | 38 ++++++++++++++------- gcc/fortran/dependency.h | 3 +- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gfortran.dg/dependency_54.f90 | 24 +++++++++++++ 5 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/dependency_54.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 622f5762a84..faca1a0657c 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2019-07-25 Thomas Koenig + + PR fortran/65819 + * dependency.h (gfc_dep_resovler): Add optional argument identical. + * dependency.c (gfc_check_dependency): Do not alway return 1 if + the symbol is the same. Pass on identical to gfc_dep_resolver. + (gfc_check_element_vs_element): Whitespace fix. + (gfc_dep_resolver): Adjust comment for function. If identical is + true, return 1 if any overlap has been found. + 2019-07-23 Steven G. Kargl PR fortran/54072 @@ -6,7 +16,7 @@ (gfc_check_transfer): Use to arguments. (gfc_check_storage_size): Ditto. (gfc_check_complex): Remove leftover comment from BOZ patch. - * primary.c (match_boz_constant): Remove leftover comment. + * primary.c (match_boz_constant): Remove leftover comment. 2019-07-23 Steven G. Kargl @@ -19,7 +29,7 @@ (match_complex_constant: Use convert_complex. * arith.h (gfc_convert_integer, gfc_convert_real, gfc_convert_complex): Remove prototypes. - * array.c (match_array_cons_element): A BOZ cannot be a data + * array.c (match_array_cons_element): A BOZ cannot be a data statement value. Jump to a common exit point. * check.c (gfc_invalid_boz): New function. Emit error or warning for a BOZ in an invalid context. @@ -32,7 +42,7 @@ constant to INTEGER in accordance to F2018. (gfc_check_achar, gfc_check_char, gfc_check_float): Use gfc_invalid_boz. Convert BOZ as needed. - (gfc_check_bge_bgt_ble_blt): Enforce F2018 requirements on BGE, + (gfc_check_bge_bgt_ble_blt): Enforce F2018 requirements on BGE, BGT, BLE, and BLT intrinsic functions. (gfc_check_cmplx): Re-organize to check kind, if present, first. Convert BOZ real and/or imaginary parts as needed in accordance to @@ -41,7 +51,7 @@ (gfc_check_dcmplx, gfc_check_dble ): Convert BOZ as needed. (gfc_check_dshift): Make dshift[lr] conform to F2018 standard. gfc_check_float (gfc_expr *a) - (gfc_check_iand_ieor_ior): Make IAND, IEOR, and IOR conform to + (gfc_check_iand_ieor_ior): Make IAND, IEOR, and IOR conform to F2018 standard. (gfc_check_int): Conform to F2018 standard. (gfc_check_intconv): Deprecate SHORT and LONG aliases for INT2 and @@ -62,7 +72,7 @@ INTEGER or REAL. * gfortran.h (gfc_expr): Add a boz component. Remove is_boz component. (gfc_boz2int, gfc_boz2real, gfc_invalid_boz): New prototypes. - * interface.c (gfc_extend_assign): Guard against replacing an + * interface.c (gfc_extend_assign): Guard against replacing an intrinsic involving a BOZ literal constant on RHS. * invoke.texi: Doument -fallow-invalid-boz. * lang.opt: New option. -fallow-invalid-boz. diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c index be330e276c2..da4a37c9e95 100644 --- a/gcc/fortran/dependency.c +++ b/gcc/fortran/dependency.c @@ -1351,13 +1351,10 @@ gfc_check_dependency (gfc_expr *expr1, gfc_expr *expr2, bool identical) return 0; } - if (identical) - return 1; - /* Identical and disjoint ranges return 0, overlapping ranges return 1. */ if (expr1->ref && expr2->ref) - return gfc_dep_resolver (expr1->ref, expr2->ref, NULL); + return gfc_dep_resolver (expr1->ref, expr2->ref, NULL, identical); return 1; @@ -1884,6 +1881,7 @@ gfc_check_element_vs_element (gfc_ref *lref, gfc_ref *rref, int n) if (i > -2) return GFC_DEP_NODEP; + return GFC_DEP_EQUAL; } @@ -2084,13 +2082,15 @@ ref_same_as_full_array (gfc_ref *full_ref, gfc_ref *ref) /* Finds if two array references are overlapping or not. Return value - 2 : array references are overlapping but reversal of one or + 2 : array references are overlapping but reversal of one or more dimensions will clear the dependency. - 1 : array references are overlapping. - 0 : array references are identical or not overlapping. */ + 1 : array references are overlapping, or identical is true and + there is some kind of overlap. + 0 : array references are identical or not overlapping. */ int -gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse) +gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse, + bool identical) { int n; int m; @@ -2124,11 +2124,15 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse) case REF_ARRAY: + /* For now, treat all coarrays as dangerous. */ + if (lref->u.ar.codimen || rref->u.ar.codimen) + return 1; + if (ref_same_as_full_array (lref, rref)) - return 0; + return identical; if (ref_same_as_full_array (rref, lref)) - return 0; + return identical; if (lref->u.ar.dimen != rref->u.ar.dimen) { @@ -2180,6 +2184,8 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse) gcc_assert (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT && lref->u.ar.dimen_type[n] == DIMEN_ELEMENT); this_dep = gfc_check_element_vs_element (rref, lref, n); + if (identical && this_dep == GFC_DEP_EQUAL) + this_dep = GFC_DEP_OVERLAP; } /* If any dimension doesn't overlap, we have no dependency. */ @@ -2240,6 +2246,9 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse) know the worst one.*/ update_fin_dep: + if (identical && this_dep == GFC_DEP_EQUAL) + this_dep = GFC_DEP_OVERLAP; + if (this_dep > fin_dep) fin_dep = this_dep; } @@ -2253,7 +2262,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse) /* Exactly matching and forward overlapping ranges don't cause a dependency. */ - if (fin_dep < GFC_DEP_BACKWARD) + if (fin_dep < GFC_DEP_BACKWARD && !identical) return 0; /* Keep checking. We only have a dependency if @@ -2267,11 +2276,14 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse) rref = rref->next; } + /* Assume the worst if we nest to different depths. */ + if (lref || rref) + return 1; + /* If we haven't seen any array refs then something went wrong. */ gcc_assert (fin_dep != GFC_DEP_ERROR); - /* Assume the worst if we nest to different depths. */ - if (lref || rref) + if (identical && fin_dep != GFC_DEP_NODEP) return 1; return fin_dep == GFC_DEP_OVERLAP; diff --git a/gcc/fortran/dependency.h b/gcc/fortran/dependency.h index dd3088713e4..eca60f7d8e5 100644 --- a/gcc/fortran/dependency.h +++ b/gcc/fortran/dependency.h @@ -37,7 +37,8 @@ int gfc_check_fncall_dependency (gfc_expr *, sym_intent, gfc_symbol *, int gfc_check_dependency (gfc_expr *, gfc_expr *, bool); int gfc_expr_is_one (gfc_expr *, int); -int gfc_dep_resolver(gfc_ref *, gfc_ref *, gfc_reverse *); +int gfc_dep_resolver (gfc_ref *, gfc_ref *, gfc_reverse *, + bool identical = false); int gfc_are_equivalenced_arrays (gfc_expr *, gfc_expr *); gfc_expr * gfc_discard_nops (gfc_expr *); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 948acc0c771..ea5d239661a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-07-25 Thomas Koenig + + PR fortran/65819 + * gfortran.dg/dependency_54.f90: New test. + 2019-07-25 Eric Botcazou * gnat.dg/case_optimization3.ad[sb]: New test. diff --git a/gcc/testsuite/gfortran.dg/dependency_54.f90 b/gcc/testsuite/gfortran.dg/dependency_54.f90 new file mode 100644 index 00000000000..f738ed81d6c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_54.f90 @@ -0,0 +1,24 @@ +! { dg-do run } +! { dg-additional-options "-fdump-tree-original -ffrontend-optimize" } +! PR 65819 - this used to cause a temporary in matmul inlining. +! Check that these are absent by looking for the names of the +! temporary variables. +program main + implicit none + real, dimension(3,3,3) :: f + real, dimension(3,3) :: res + real, dimension(2,3,3) :: backup + integer :: three + integer :: i + + data f(1,:,:) /9*-42./ + data f(2:3,:,:) /2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61/ + data res /652, 772, 984, 2010, 2406, 3082, 3402, 4086, 5242/ + three = 3 + backup = f(2:3,:,:) + f(1, 1:three, :) = matmul(f(2,1:3,2:3), f(3,2:3,:)) + if (any (res /= f(1,:,:))) stop 1 + if (any (f(2:3,:,:) /= backup)) stop 2 +end program main +! { dg-final { scan-tree-dump-not "mma" "original" } } +! { dg-final { scan-tree-dump-not "mmb" "original" } } -- 2.30.2