From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) by sourceware.org (Postfix) with ESMTPS id 51382385803B; Wed, 15 Dec 2021 15:55:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 51382385803B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com IronPort-SDR: 4VxD3vMUpqt1i8H/kVasv0xVs/FKGkDUGTDpMWnPtJZZCFNw8FaIuwMsBIoGmRT4j/6JBo/mru wlyLOqxq0wdZBd/7rD1tqasetGhbCek+Rsy6faCpIe6wBnxLGsmLCmSpK19YqMdVICg4dzwf2U w3q2Dz7/0mSbzz0UQMfj//QEbaio22WkkCaGLeeiC/0aG1zMm0PjPJnzsBEVOze7HmMt/G25Ot uQ9g/TEg9h5zm/JUY5BynVpHxhI8AW+1tmPFRRgONybkNgosar6Mrcp2dCLB3oZRhhsC6c92Bg /3vrdd3yjv/Z38Kuo9r5g91l X-IronPort-AV: E=Sophos;i="5.88,207,1635235200"; d="scan'208";a="69736558" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa2.mentor.iphmx.com with ESMTP; 15 Dec 2021 07:55:49 -0800 IronPort-SDR: Q7XZst4v0k1uGrjIwDDNW0747AX8+yBRlCXs6B7lHKwkAKXtkxfX/VlsrkE5A74SkPlKP41LIP 4R8nUgxVGH70dxPMyMqcAOcJZLv0oNqj+lpf8wpPn0L5LZ6uIWggFz3VJinyachJVWjRMVlmDf cuDEDs3YP6ScMcAdGwdEUIVGMC/3lVmwEBtHgKyLuLjrpHsxPcjp6QS2ftjlaMZozU3BUkHDts 126fObBhZs+RWy3WWu5IMS69Xrc5km6ivVGLGOSBxeCZah0e5CXhrUKMwYPlSH++KDla1tWkrp RxU= From: Frederik Harwath To: CC: , , , Subject: [PATCH 13/40] Fortran: Delinearize array accesses Date: Wed, 15 Dec 2021 16:54:20 +0100 Message-ID: <20211215155447.19379-14-frederik@codesourcery.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211215155447.19379-1-frederik@codesourcery.com> References: <20211215155447.19379-1-frederik@codesourcery.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-11.mgc.mentorg.com (139.181.222.11) To SVR-IES-MBX-04.mgc.mentorg.com (139.181.222.4) X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Dec 2021 15:55:54 -0000 The Fortran front end presently linearizes accesses to multi-dimensional arrays by combining the indices for the various dimensions into a series of explicit multiplies and adds with refactoring to allow CSE of invariant parts of the computation. Unfortunately this representation interferes with Graphite-based loop optimizations. It is difficult to recover the original multi-dimensional form of the access by the time loop optimizations run because parts of it have already been optimized away or into a form that is not easily recognizable, so it seems better to have the Fortran front end produce delinearized accesses to begin with, a set of nested ARRAY_REFs similar to the existing behavior of the C and C++ front ends. This is a long-standing problem that has previously been discussed e.g. in PR 14741 and PR61000. This patch is an initial implementation for explicit array accesses only; it doesn't handle the accesses generated during scalarization of whole-array or array-section operations, which follow a different code path. Co-Authored-By: Tobias Burnus gcc/ChangeLog: * expr.c (get_inner_reference): Handle NOP_EXPR. gcc/fortran/ChangeLog: * lang.opt: Document -param=3Ddelinearize. * trans-array.c: (get_class_array_vptr): New function. (get_array_lbound): New function. (get_array_ubound): New function. (gfc_conv_array_ref): Implement main delinearization logic. (build_array_ref): Adjust. gcc/testsuite/ChangeLog: * gfortran.dg/assumed_type_2.f90: Adjust test expectations. * gfortran.dg/goacc/kernels-loop-inner.f95: Likewise. * gfortran.dg/gomp/affinity-clause-1.f90: Likewise. * gfortran.dg/graphite/block-2.f: Likewise. * gfortran.dg/graphite/block-3.f90: Likewise. * gfortran.dg/graphite/block-4.f90: Likewise. * gfortran.dg/graphite/id-9.f: Likewise. * gfortran.dg/inline_matmul_16.f90: Likewise. * gfortran.dg/inline_matmul_24.f90: Likewise. * gfortran.dg/no_arg_check_2.f90: Likewise. * gfortran.dg/pr32921.f: Likewise. * gfortran.dg/reassoc_4.f: Likewise. * gfortran.dg/vect/fast-math-mgrid-resid.f: Likewise. --- gcc/expr.c | 1 + gcc/fortran/lang.opt | 4 + gcc/fortran/trans-array.c | 321 +++++++++++++----- gcc/testsuite/gfortran.dg/assumed_type_2.f90 | 6 +- .../gfortran.dg/goacc/kernels-loop-inner.f95 | 2 +- .../gfortran.dg/gomp/affinity-clause-1.f90 | 2 +- gcc/testsuite/gfortran.dg/graphite/block-2.f | 9 +- .../gfortran.dg/graphite/block-3.f90 | 2 +- .../gfortran.dg/graphite/block-4.f90 | 2 +- gcc/testsuite/gfortran.dg/graphite/id-9.f | 2 +- .../gfortran.dg/inline_matmul_16.f90 | 2 + .../gfortran.dg/inline_matmul_24.f90 | 2 +- gcc/testsuite/gfortran.dg/no_arg_check_2.f90 | 6 +- gcc/testsuite/gfortran.dg/pr32921.f | 2 +- gcc/testsuite/gfortran.dg/reassoc_4.f | 2 +- .../gfortran.dg/vect/fast-math-mgrid-resid.f | 1 + 16 files changed, 270 insertions(+), 96 deletions(-) diff --git a/gcc/expr.c b/gcc/expr.c index eb33643bd770..188905b4fe4d 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -7759,6 +7759,7 @@ get_inner_reference (tree exp, poly_int64_pod *pbitsi= ze, break; case VIEW_CONVERT_EXPR: + case NOP_EXPR: break; case MEM_REF: diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index a202c04c4a25..25c5a5a32c41 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -521,6 +521,10 @@ fdefault-real-16 Fortran Var(flag_default_real_16) Set the default real kind to an 16 byte wide type. +-param=3Ddelinearize=3D +Common Joined UInteger Var(flag_delinearize_aref) Init(1) IntegerRange(0,1= ) Param Optimization +Delinearize array references. + fdollar-ok Fortran Var(flag_dollar_ok) Allow dollar signs in entity names. diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 5ceb261b6989..e84b4cb55f05 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -3747,11 +3747,9 @@ add_to_offset (tree *cst_offset, tree *offset, tree = t) } } - static tree -build_array_ref (tree desc, tree offset, tree decl, tree vptr) +get_class_array_vptr (tree desc, tree vptr) { - tree tmp; tree type; tree cdesc; @@ -3775,19 +3773,74 @@ build_array_ref (tree desc, tree offset, tree decl,= tree vptr) && GFC_CLASS_TYPE_P (TYPE_CANONICAL (type))) vptr =3D gfc_class_vptr_get (TREE_OPERAND (cdesc, 0)); } + return vptr; +} +static tree +build_array_ref (tree desc, tree offset, tree decl, tree vptr) +{ + tree tmp; + vptr =3D get_class_array_vptr (desc, vptr); tmp =3D gfc_conv_array_data (desc); tmp =3D build_fold_indirect_ref_loc (input_location, tmp); tmp =3D gfc_build_array_ref (tmp, offset, decl, vptr); return tmp; } +/* Get the declared lower bound for rank N of array DECL which might + be either a bare array or a descriptor. This differs from + gfc_conv_array_lbound because it gets information for temporary array + objects from AR instead of the descriptor (they can differ). */ + +static tree +get_array_lbound (tree decl, int n, gfc_symbol *sym, + gfc_array_ref *ar, gfc_se *se) +{ + if (sym->attr.temporary) + { + gfc_se tmpse; + gfc_init_se (&tmpse, se); + gfc_conv_expr_type (&tmpse, ar->as->lower[n], gfc_array_index_type); + gfc_add_block_to_block (&se->pre, &tmpse.pre); + return tmpse.expr; + } + else + return gfc_conv_array_lbound (decl, n); +} + +/* Similarly for the upper bound. */ +static tree +get_array_ubound (tree decl, int n, gfc_symbol *sym, + gfc_array_ref *ar, gfc_se *se) +{ + if (sym->attr.temporary) + { + gfc_se tmpse; + gfc_init_se (&tmpse, se); + gfc_conv_expr_type (&tmpse, ar->as->upper[n], gfc_array_index_type); + gfc_add_block_to_block (&se->pre, &tmpse.pre); + return tmpse.expr; + } + else + return gfc_conv_array_ubound (decl, n); +} + /* Build an array reference. se->expr already holds the array descriptor. This should be either a variable, indirect variable reference or compon= ent reference. For arrays which do not have a descriptor, se->expr will be the data pointer. - a(i, j, k) =3D base[offset + i * stride[0] + j * stride[1] + k * stride= [2]]*/ + + There are two strategies here. In the traditional case, multidimension= al + arrays are explicitly linearized into a one-dimensional array, with the + index computed as if by + a(i, j, k) =3D base[offset + i * stride[0] + j * stride[1] + k * stride= [2]] + + However, we can often get better code using the Graphite framework + and scalar evolutions in the middle end, which expects to see + multidimensional array accesses represented as nested ARRAY_REFs, simil= ar + to what the C/C++ front ends produce. Delinearization is controlled + by flag_delinearize_aref. */ void gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, @@ -3798,11 +3851,16 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar= , gfc_expr *expr, tree tmp; tree stride; tree decl =3D NULL_TREE; + tree cooked_decl =3D NULL_TREE; + tree vptr =3D se->class_vptr; gfc_se indexse; gfc_se tmpse; gfc_symbol * sym =3D expr->symtree->n.sym; char *var_name =3D NULL; + tree aref =3D NULL_TREE; + tree atype =3D NULL_TREE; + /* Handle coarrays. */ if (ar->dimen =3D=3D 0) { gcc_assert (ar->codimen || sym->attr.select_rank_temporary @@ -3862,15 +3920,160 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * a= r, gfc_expr *expr, } } + /* Per comments above, DECL is not always a declaration. It may be + either a variable, indirect variable reference, or component + reference. It may have array or pointer type, or it may be a + descriptor with RECORD_TYPE. */ decl =3D se->expr; if (IS_CLASS_ARRAY (sym) && sym->attr.dummy && ar->as->type !=3D AS_DEFE= RRED) decl =3D sym->backend_decl; - cst_offset =3D offset =3D gfc_index_zero_node; - add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (decl)); + /* A pointer array component can be detected from its field decl. Fix + the descriptor, mark the resulting variable decl and store it in + COOKED_DECL to pass to gfc_build_array_ref. */ + if (get_CFI_desc (sym, expr, &cooked_decl, ar)) + cooked_decl =3D build_fold_indirect_ref_loc (input_location, cooked_de= cl); + if (!expr->ts.deferred && !sym->attr.codimension + && is_pointer_array (se->expr)) + { + if (TREE_CODE (se->expr) =3D=3D COMPONENT_REF) + cooked_decl =3D se->expr; + else if (TREE_CODE (se->expr) =3D=3D INDIRECT_REF) + cooked_decl =3D TREE_OPERAND (se->expr, 0); + else + cooked_decl =3D se->expr; + } + else if (expr->ts.deferred + || (sym->ts.type =3D=3D BT_CHARACTER + && sym->attr.select_type_temporary)) + { + if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr))) + { + cooked_decl =3D se->expr; + if (TREE_CODE (cooked_decl) =3D=3D INDIRECT_REF) + cooked_decl =3D TREE_OPERAND (cooked_decl, 0); + } + else + cooked_decl =3D sym->backend_decl; + } + else if (sym->ts.type =3D=3D BT_CLASS) + { + if (UNLIMITED_POLY (sym)) + { + gfc_expr *class_expr =3D gfc_find_and_cut_at_last_class_ref (expr= ); + gfc_init_se (&tmpse, NULL); + gfc_conv_expr (&tmpse, class_expr); + if (!se->class_vptr) + vptr =3D gfc_class_vptr_get (tmpse.expr); + gfc_free_expr (class_expr); + cooked_decl =3D tmpse.expr; + } + else + cooked_decl =3D NULL_TREE; + } + + /* Find the base of the array; this normally has ARRAY_TYPE. */ + tree base =3D build_fold_indirect_ref_loc (input_location, + gfc_conv_array_data (se->expr)); + tree type =3D TREE_TYPE (base); - /* Calculate the offsets from all the dimensions. Make sure to associat= e - the final offset so that we form a chain of loop invariant summands. = */ + /* Handle special cases, copied from gfc_build_array_ref. After we get + through this, we know TYPE definitely is an ARRAY_TYPE. */ + if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) =3D=3D 0) + { + gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0); + se->expr =3D fold_convert (TYPE_MAIN_VARIANT (type), base); + return; + } + if (TREE_CODE (type) !=3D ARRAY_TYPE) + { + gcc_assert (cooked_decl =3D=3D NULL_TREE); + se->expr =3D base; + return; + } + + /* Check for cases where we cannot delinearize. */ + + bool delinearize =3D flag_delinearize_aref; + + /* There is no point in trying to delinearize 1-dimensional arrays. */ + if (ar->dimen =3D=3D 1) + delinearize =3D false; + + if (delinearize + && (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr)) + || (DECL_P (se->expr) + && DECL_LANG_SPECIFIC (se->expr) + && GFC_DECL_SAVED_DESCRIPTOR (se->expr)))) + { + /* Descriptor arrays that may not be contiguous cannot + be delinearized without using the stride in the descriptor, + which generally involves introducing a division operation. + That's unlikely to produce optimal code, so avoid doing it. */ + tree desc =3D se->expr; + if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr))) + desc =3D GFC_DECL_SAVED_DESCRIPTOR (se->expr); + tree tmptype =3D TREE_TYPE (desc); + if (POINTER_TYPE_P (tmptype)) + tmptype =3D TREE_TYPE (tmptype); + enum gfc_array_kind akind =3D GFC_TYPE_ARRAY_AKIND (tmptype); + if (akind !=3D GFC_ARRAY_ASSUMED_SHAPE_CONT + && akind !=3D GFC_ARRAY_ASSUMED_RANK_CONT + && akind !=3D GFC_ARRAY_ALLOCATABLE + && akind !=3D GFC_ARRAY_POINTER_CONT) + delinearize =3D false; + } + + /* See gfc_build_array_ref in trans.c. If we have a cooked_decl or + vptr, then we most likely have to do pointer arithmetic using a + linearized array offset. */ + if (delinearize && cooked_decl) + delinearize =3D false; + else if (delinearize && get_class_array_vptr (se->expr, vptr)) + delinearize =3D false; + + if (!delinearize) + { + /* Initialize the offset from the array descriptor. This accounts + for the array base being something other than zero. */ + cst_offset =3D offset =3D gfc_index_zero_node; + add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (decl)); + } + else + { + /* If we are delinearizing, build up the nested array type using the + dimension information we have for each rank. */ + atype =3D TREE_TYPE (type); + for (n =3D 0; n < ar->dimen; n++) + { + /* We're working from the outermost nested array reference inward + in this step. ATYPE is the element type for the access in + this rank; build the new array type based on the bounds + information and store it back into ATYPE for the next rank's + processing. */ + tree lbound =3D get_array_lbound (decl, n, sym, ar, se); + tree ubound =3D get_array_ubound (decl, n, sym, ar, se); + tree dimen =3D build_range_type (TREE_TYPE (lbound), + lbound, ubound); + atype =3D build_array_type (atype, dimen); + + /* Emit a DECL_EXPR for the array type so the gimplification of + its type sizes works correctly. */ + if (! TYPE_NAME (atype)) + TYPE_NAME (atype) =3D build_decl (UNKNOWN_LOCATION, TYPE_DECL, + NULL_TREE, atype); + gfc_add_expr_to_block (&se->pre, + build1 (DECL_EXPR, atype, + TYPE_NAME (atype))); + } + + /* Cast base to the innermost array type. */ + if (DECL_P (base)) + TREE_ADDRESSABLE (base) =3D 1; + aref =3D build1 (NOP_EXPR, atype, base); + } + + /* Process indices in reverse order. */ for (n =3D ar->dimen - 1; n >=3D 0; n--) { /* Calculate the index for this dimension. */ @@ -3888,16 +4091,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar,= gfc_expr *expr, indexse.expr =3D save_expr (indexse.expr); /* Lower bound. */ - tmp =3D gfc_conv_array_lbound (decl, n); - if (sym->attr.temporary) - { - gfc_init_se (&tmpse, se); - gfc_conv_expr_type (&tmpse, ar->as->lower[n], - gfc_array_index_type); - gfc_add_block_to_block (&se->pre, &tmpse.pre); - tmp =3D tmpse.expr; - } - + tmp =3D get_array_lbound (decl, n, sym, ar, se); cond =3D fold_build2_loc (input_location, LT_EXPR, logical_type_n= ode, indexse.expr, tmp); msg =3D xasprintf ("Index '%%ld' of dimension %d of array '%s' " @@ -3912,16 +4106,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar,= gfc_expr *expr, arrays. */ if (n < ar->dimen - 1 || ar->as->type !=3D AS_ASSUMED_SIZE) { - tmp =3D gfc_conv_array_ubound (decl, n); - if (sym->attr.temporary) - { - gfc_init_se (&tmpse, se); - gfc_conv_expr_type (&tmpse, ar->as->upper[n], - gfc_array_index_type); - gfc_add_block_to_block (&se->pre, &tmpse.pre); - tmp =3D tmpse.expr; - } - + tmp =3D get_array_ubound (decl, n, sym, ar, se); cond =3D fold_build2_loc (input_location, GT_EXPR, logical_type_node, indexse.expr, tmp)= ; msg =3D xasprintf ("Index '%%ld' of dimension %d of array '%s= ' " @@ -3934,65 +4119,41 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar= , gfc_expr *expr, } } - /* Multiply the index by the stride. */ - stride =3D gfc_conv_array_stride (decl, n); - tmp =3D fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_= type, - indexse.expr, stride); - - /* And add it to the total. */ - add_to_offset (&cst_offset, &offset, tmp); - } - - if (!integer_zerop (cst_offset)) - offset =3D fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, offset, cst_offset); - - /* A pointer array component can be detected from its field decl. Fix - the descriptor, mark the resulting variable decl and pass it to - build_array_ref. */ - decl =3D NULL_TREE; - if (get_CFI_desc (sym, expr, &decl, ar)) - decl =3D build_fold_indirect_ref_loc (input_location, decl); - if (!expr->ts.deferred && !sym->attr.codimension - && is_pointer_array (se->expr)) - { - if (TREE_CODE (se->expr) =3D=3D COMPONENT_REF) - decl =3D se->expr; - else if (TREE_CODE (se->expr) =3D=3D INDIRECT_REF) - decl =3D TREE_OPERAND (se->expr, 0); - else - decl =3D se->expr; - } - else if (expr->ts.deferred - || (sym->ts.type =3D=3D BT_CHARACTER - && sym->attr.select_type_temporary)) - { - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr))) + if (!delinearize) { - decl =3D se->expr; - if (TREE_CODE (decl) =3D=3D INDIRECT_REF) - decl =3D TREE_OPERAND (decl, 0); + /* Multiply the index by the stride. */ + stride =3D gfc_conv_array_stride (decl, n); + tmp =3D fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, + indexse.expr, stride); + + /* And add it to the total. */ + add_to_offset (&cst_offset, &offset, tmp); } else - decl =3D sym->backend_decl; - } - else if (sym->ts.type =3D=3D BT_CLASS) - { - if (UNLIMITED_POLY (sym)) { - gfc_expr *class_expr =3D gfc_find_and_cut_at_last_class_ref (expr= ); - gfc_init_se (&tmpse, NULL); - gfc_conv_expr (&tmpse, class_expr); - if (!se->class_vptr) - se->class_vptr =3D gfc_class_vptr_get (tmpse.expr); - gfc_free_expr (class_expr); - decl =3D tmpse.expr; + /* Peel off a layer of array nesting from ATYPE to + to get the result type of the new ARRAY_REF. */ + atype =3D TREE_TYPE (atype); + aref =3D build4 (ARRAY_REF, atype, aref, indexse.expr, + NULL_TREE, NULL_TREE); } - else - decl =3D NULL_TREE; } - se->expr =3D build_array_ref (se->expr, offset, decl, se->class_vptr); + if (!delinearize) + { + /* Build a linearized array reference using the offset from all + dimensions. */ + if (!integer_zerop (cst_offset)) + offset =3D fold_build2_loc (input_location, PLUS_EXPR, + gfc_array_index_type, offset, cst_offset)= ; + se->class_vptr =3D vptr; + vptr =3D get_class_array_vptr (se->expr, vptr); + se->expr =3D gfc_build_array_ref (base, offset, cooked_decl, vptr); + } + else + /* Return the outermost ARRAY_REF we already built. */ + se->expr =3D aref; } diff --git a/gcc/testsuite/gfortran.dg/assumed_type_2.f90 b/gcc/testsuite/g= fortran.dg/assumed_type_2.f90 index 5d3cd7eaece9..07be87ef1eb6 100644 --- a/gcc/testsuite/gfortran.dg/assumed_type_2.f90 +++ b/gcc/testsuite/gfortran.dg/assumed_type_2.f90 @@ -147,12 +147,12 @@ end ! { dg-final { scan-tree-dump-times "sub_scalar .&scalar_int," 1 "original= " } } ! { dg-final { scan-tree-dump-times "sub_scalar .&scalar_t1," 1 "original"= } } -! { dg-final { scan-tree-dump-times "sub_scalar .&array_int.1.," 1 "origin= al" } } +! { dg-final { scan-tree-dump-times "sub_scalar .&.*array_int" 1 "original= " } } ! { dg-final { scan-tree-dump-times "sub_scalar .&scalar_t1," 1 "original"= } } -! { dg-final { scan-tree-dump-times "sub_scalar .&\\(.\\(real.kind=3D4..0:= . . restrict\\) array_real_alloc.data" 1 "original" } } +! { dg-final { scan-tree-dump-times "sub_scalar .&.*real.kind=3D4..0.*rest= rict.*array_real_alloc.data" 1 "original" } } ! { dg-final { scan-tree-dump-times "sub_scalar .\\(character.kind=3D1..1:= 1. .\\) .array_char_ptr.data" 1 "original" } } -! { dg-final { scan-tree-dump-times "sub_scalar .&\\(.\\(struct t2.0:. . r= estrict\\) array_t2_alloc.data" 1 "original" } } +! { dg-final { scan-tree-dump-times "sub_scalar .&.*struct t2.0:..*restric= t.*array_t2_alloc.data" 1 "original" } } ! { dg-final { scan-tree-dump-times "sub_scalar .\\(struct t3 .\\) .array_= t3_ptr.data" 1 "original" } } ! { dg-final { scan-tree-dump-times "sub_scalar .\\(struct t1 .\\) array_c= lass_t1_alloc._data.data" 1 "original" } } ! { dg-final { scan-tree-dump-times "sub_scalar .\\(struct t1 .\\) \\(arra= y_class_t1_ptr._data.dat" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/goacc/kernels-loop-inner.f95 b/gcc/t= estsuite/gfortran.dg/goacc/kernels-loop-inner.f95 index a3ad591f926c..d8d14c42be01 100644 --- a/gcc/testsuite/gfortran.dg/goacc/kernels-loop-inner.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/kernels-loop-inner.f95 @@ -7,7 +7,7 @@ program main integer :: a(100,100), b(100,100) integer :: i, j, d - !$acc kernels ! { dg-message "optimized: assigned OpenACC seq loop para= llelism" } + !$acc kernels ! { dg-message "optimized: assigned OpenACC gang loop par= allelism" } do i=3D1,100 do j=3D1,100 a(i,j) =3D 1 diff --git a/gcc/testsuite/gfortran.dg/gomp/affinity-clause-1.f90 b/gcc/tes= tsuite/gfortran.dg/gomp/affinity-clause-1.f90 index 13bdd36d0b4d..51c6013565a1 100644 --- a/gcc/testsuite/gfortran.dg/gomp/affinity-clause-1.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-1.f90 @@ -22,7 +22,7 @@ end ! { dg-final { scan-tree-dump-times "D\\.\[0-9\]+ =3D .integer.kind=3D4.. = __builtin_cosf ..real.kind=3D4.. a \\+ 1.0e\\+0\\);" 2 "original" } } -! { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\= \(integer\\(kind=3D4\\) jj=3D2:5:2, integer\\(kind=3D4\\) i=3DD\\.\[0-9\]+:= 5:1\\):\\*\\(c_char \\*\\) &b\\\[.* ? \\+ -1\\\]\\) affinity\\(iterator= \\(integer\\(kind=3D4\\) jj=3D2:5:2, integer\\(kind=3D4\\) i=3DD\\.\[0-9\]+= :5:1\\):\\*\\(c_char \\*\\) &d\\\[\\(.*jj \\* 5 \\+ .* ?\\) \\+ -6\\\]\= \)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\= \(integer\\(kind=3D4\\) jj=3D2:5:2, integer\\(kind=3D4\\) i=3DD\\.\[0-9\]+:= 5:1\\):\\*\\(c_char \\*\\) &b\\\[.* ? \\+ -1\\\]\\) affinity\\(iterator= \\(integer\\(kind=3D4\\) jj=3D2:5:2, integer\\(kind=3D4\\) i=3DD\\.\[0-9\]+= :5:1\\):\\*\\(c_char \\*\\) &\\(\\(integer\\(kind.*?d\\).*?$" 1 "original" = } } ! { dg final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\= \(integer\\(kind=3D4\\) i=3DD.3938:5:1\\):\\*\\(c_char \\*\\) &b\\\[\\(.* <= ?i>? \\+ -1\\\]\\) affinity\\(iterator\\(integer\\(kind=3D4\\) i=3DD\\.\[0-= 9\]+:5:1\\):\\*\\(c_char \\*\\) &d\\\[\\(\\(integer\\(kind=3D8\\)\\) i \\+ = -1\\) \\* 6\\\]\\)" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/block-2.f b/gcc/testsuite/g= fortran.dg/graphite/block-2.f index bea8ddeb8267..266da378c5d9 100644 --- a/gcc/testsuite/gfortran.dg/graphite/block-2.f +++ b/gcc/testsuite/gfortran.dg/graphite/block-2.f @@ -1,5 +1,11 @@ ! { dg-do compile } ! { dg-additional-options "-std=3Dlegacy" } + +! ldist introduces a __builtin_memset for the first loop and hence +! breaks the testcases's assumption regarding the number of SCoPs +! because Graphite cannot deal with the call. +! { dg-additional-options "-fdisable-tree-ldist" } + SUBROUTINE MATRIX_MUL_UNROLLED (A, B, C, L, M, N) DIMENSION A(L,M), B(M,N), C(L,N) @@ -18,5 +24,4 @@ RETURN END -! Disabled for now as it requires delinearization. -! { dg-final { scan-tree-dump-times "number of SCoPs: 2" 1 "graphite" { xf= ail *-*-* } } } +! { dg-final { scan-tree-dump-times "number of SCoPs: 2" 1 "graphite" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/block-3.f90 b/gcc/testsuite= /gfortran.dg/graphite/block-3.f90 index 452de7349050..0edca92bb894 100644 --- a/gcc/testsuite/gfortran.dg/graphite/block-3.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/block-3.f90 @@ -12,6 +12,6 @@ enddo end subroutine matrix_multiply -! { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite" { xf= ail *-*-* } } } +! { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite" } } ! { dg-final { scan-tree-dump-times "will be loop blocked" 1 "graphite" { = xfail *-*-* } } } diff --git a/gcc/testsuite/gfortran.dg/graphite/block-4.f90 b/gcc/testsuite= /gfortran.dg/graphite/block-4.f90 index 42af5b62444e..f2aed98bcf82 100644 --- a/gcc/testsuite/gfortran.dg/graphite/block-4.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/block-4.f90 @@ -15,6 +15,6 @@ enddo end subroutine matrix_multiply -! { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite" { xf= ail *-*-* } } } +! { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite" } } ! { dg-final { scan-tree-dump-times "will be loop blocked" 1 "graphite" { = xfail *-*-* } } } diff --git a/gcc/testsuite/gfortran.dg/graphite/id-9.f b/gcc/testsuite/gfor= tran.dg/graphite/id-9.f index c93937088972..885a9dfaa1bb 100644 --- a/gcc/testsuite/gfortran.dg/graphite/id-9.f +++ b/gcc/testsuite/gfortran.dg/graphite/id-9.f @@ -8,7 +8,7 @@ do l=3D1,3 do k=3D1,l enddo - bar(k,l)=3Dbar(k,l)+(v3b-1.d0) + bar(k,l)=3Dbar(k,l)+(v3b-1.d0) ! { dg-bogus ".*iterat= ion 2 invokes undefined behavior" "TODO" { xfail *-*-* } } enddo enddo do m=3D1,ne diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_16.f90 b/gcc/testsuite= /gfortran.dg/inline_matmul_16.f90 index 580cb1ac9393..2a7f63b9c963 100644 --- a/gcc/testsuite/gfortran.dg/inline_matmul_16.f90 +++ b/gcc/testsuite/gfortran.dg/inline_matmul_16.f90 @@ -1,5 +1,7 @@ ! { dg-do run } ! { dg-options "-ffrontend-optimize -fdump-tree-optimized -Wrealloc-lhs -f= inline-matmul-limit=3D1000 -O" } +! { dg-additional-options "--param delinearize=3D0" } TODO + ! PR 66094: Check functionality for MATMUL(TRANSPOSE(A),B)) for two-dimens= ional arrays program main implicit none diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_24.f90 b/gcc/testsuite= /gfortran.dg/inline_matmul_24.f90 index 3168d5f10064..8d84f3cdb01b 100644 --- a/gcc/testsuite/gfortran.dg/inline_matmul_24.f90 +++ b/gcc/testsuite/gfortran.dg/inline_matmul_24.f90 @@ -39,4 +39,4 @@ program testMATMUL call abort() end if end program testMATMUL -! { dg-final { scan-tree-dump-times "gamma5\\\[__var_1_do \\* 4 \\+ __var_= 2_do\\\]|gamma5\\\[NON_LVALUE_EXPR <__var_1_do> \\* 4 \\+ NON_LVALUE_EXPR <= __var_2_do>\\\]" 1 "original" } } +! { dg-final { scan-tree-dump-times "gamma5.*\\\[NON_LVALUE_EXPR <__var_1_= do>\\\]\\\[NON_LVALUE_EXPR <__var_2_do>\\\]" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/no_arg_check_2.f90 b/gcc/testsuite/g= fortran.dg/no_arg_check_2.f90 index 3570b9719ebb..0900dd82646f 100644 --- a/gcc/testsuite/gfortran.dg/no_arg_check_2.f90 +++ b/gcc/testsuite/gfortran.dg/no_arg_check_2.f90 @@ -129,12 +129,12 @@ end ! { dg-final { scan-tree-dump-times "sub_scalar .&scalar_int," 1 "original= " } } ! { dg-final { scan-tree-dump-times "sub_scalar .&scalar_t1," 1 "original"= } } -! { dg-final { scan-tree-dump-times "sub_scalar .&array_int.1.," 1 "origin= al" } } +! { dg-final { scan-tree-dump-times "sub_scalar .&.*array_int" 1 "original= " } } ! { dg-final { scan-tree-dump-times "sub_scalar .&scalar_t1," 1 "original"= } } -! { dg-final { scan-tree-dump-times "sub_scalar .&\\(.\\(real.kind=3D4..0:= . . restrict\\) array_real_alloc.data" 1 "original" } } +! { dg-final { scan-tree-dump-times "sub_scalar .&.*real.kind=3D4..0.*rest= rict.*array_real_alloc.data" 1 "original" } } ! { dg-final { scan-tree-dump-times "sub_scalar .\\(character.kind=3D1..1:= 1. .\\) .array_char_ptr.data" 1 "original" } } -! { dg-final { scan-tree-dump-times "sub_scalar .&\\(.\\(struct t2.0:. . r= estrict\\) array_t2_alloc.data" 1 "original" } } +! { dg-final { scan-tree-dump-times "sub_scalar .&.*struct t2.0:..*restric= t.*array_t2_alloc.data" 1 "original" } } ! { dg-final { scan-tree-dump-times "sub_scalar .\\(struct t3 .\\) .array_= t3_ptr.data" 1 "original" } } ! { dg-final { scan-tree-dump-times "sub_scalar .\\(struct t1 .\\) array_c= lass_t1_alloc._data.data" 1 "original" } } ! { dg-final { scan-tree-dump-times "sub_scalar .\\(struct t1 .\\) \\(arra= y_class_t1_ptr._data.dat" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/pr32921.f b/gcc/testsuite/gfortran.d= g/pr32921.f index 0661208edde5..853438609c43 100644 --- a/gcc/testsuite/gfortran.dg/pr32921.f +++ b/gcc/testsuite/gfortran.dg/pr32921.f @@ -45,4 +45,4 @@ RETURN END -! { dg-final { scan-tree-dump-times "stride" 4 "lim2" } } +! { dg-final { scan-tree-dump-times "ubound" 4 "lim2" } } diff --git a/gcc/testsuite/gfortran.dg/reassoc_4.f b/gcc/testsuite/gfortran= .dg/reassoc_4.f index fdcb46e835cf..2368b76aecb2 100644 --- a/gcc/testsuite/gfortran.dg/reassoc_4.f +++ b/gcc/testsuite/gfortran.dg/reassoc_4.f @@ -1,5 +1,5 @@ ! { dg-do compile } -! { dg-options "-O3 -ffast-math -fdump-tree-reassoc1 --param max-completel= y-peeled-insns=3D200" } +! { dg-options "-O3 -ffast-math -fdump-tree-reassoc1 --param max-completel= y-peeled-insns=3D200 --param delinearize=3D0" } subroutine anisonl(w,vo,anisox,s,ii1,jj1,weight) integer ii1,jj1,i1,iii1,j1,jjj1,k1,l1,m1,n1 real*8 w(3,3),vo(3,3),anisox(3,3,3,3),s(60,60),weight diff --git a/gcc/testsuite/gfortran.dg/vect/fast-math-mgrid-resid.f b/gcc/t= estsuite/gfortran.dg/vect/fast-math-mgrid-resid.f index 08965cc5e202..6c469b1964c6 100644 --- a/gcc/testsuite/gfortran.dg/vect/fast-math-mgrid-resid.f +++ b/gcc/testsuite/gfortran.dg/vect/fast-math-mgrid-resid.f @@ -3,6 +3,7 @@ ! { dg-options "-O3 --param vect-max-peeling-for-alignment=3D0 -fpredictiv= e-commoning -fdump-tree-pcom-details -std=3Dlegacy" } ! { dg-additional-options "-mprefer-avx128" { target { i?86-*-* x86_64-*-*= } } } ! { dg-additional-options "-mzarch" { target { s390*-*-* } } } +! { dg-additional-options "--param delinearize=3D0" } TODO ******* RESID COMPUTES THE RESIDUAL: R =3D V - AU * -- 2.33.0 ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstra=DFe 201, 8= 0634 M=FCnchen; Gesellschaft mit beschr=E4nkter Haftung; Gesch=E4ftsf=FChre= r: Thomas Heurung, Frank Th=FCrauf; Sitz der Gesellschaft: M=FCnchen; Regis= tergericht M=FCnchen, HRB 106955