From: Martin Jambor Date: Fri, 4 Sep 2009 11:08:12 +0000 (+0200) Subject: re PR tree-optimization/41112 (ACATS c43205b fails at -O2 (tree-sra)) X-Git-Tag: releases/gcc-4.5.0~3679 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22fc64b4d9a300216a82f2160ffbac6fec872f16;p=thirdparty%2Fgcc.git re PR tree-optimization/41112 (ACATS c43205b fails at -O2 (tree-sra)) 2009-09-04 Martin Jambor PR tree-optimization/41112 * tree-sra.c (build_ref_for_offset_1): Signal that we cannot handle variable-bounded arrays. (expr_with_var_bounded_array_refs_p): New function. (analyze_access_subtree): Call expr_with_var_bounded_array_refs_p. * testsuite/gnat.dg/array8.adb: New test. From-SVN: r151420 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 994c36a284d2..0b160b41dba3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-09-04 Martin Jambor + + PR tree-optimization/41112 + * tree-sra.c (build_ref_for_offset_1): Signal that we cannot + handle variable-bounded arrays. + (expr_with_var_bounded_array_refs_p): New function. + (analyze_access_subtree): Call expr_with_var_bounded_array_refs_p. + 2009-09-04 Wolfgang Gellerich * config/s390/2097.md: Removed two incorrect bypasses. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f9e250297bef..d51cc0215f48 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-09-04 Martin Jambor + + PR tree-optimization/41112 + * gnat.dg/array8.adb: New test. + 2009-09-03 Jakub Jelinek * gcc.dg/guality/guality.exp: Only run guality tests if a trivial diff --git a/gcc/testsuite/gnat.dg/array8.adb b/gcc/testsuite/gnat.dg/array8.adb new file mode 100644 index 000000000000..6e18ecadf94f --- /dev/null +++ b/gcc/testsuite/gnat.dg/array8.adb @@ -0,0 +1,34 @@ +-- { dg-do compile } +-- { dg-options "-O2" } + +PROCEDURE Array8 IS + + function ID (I : Integer) return Integer is + begin + return I; + end; + + SUBTYPE STB IS INTEGER RANGE ID(-8) .. -5; + + TYPE TB IS ARRAY (STB RANGE <>) OF INTEGER; + + GENERIC + B1 : TB; + PROCEDURE PROC1; + + PROCEDURE PROC1 IS + BEGIN + IF B1'FIRST /= -8 THEN + raise Program_Error; + ELSIF B1'LAST /= ID(-5) THEN + raise Program_Error; + ELSIF B1 /= (7, 6, 5, 4) THEN + raise Program_Error; + END IF; + END; + + PROCEDURE PROC2 IS NEW PROC1 ((7, 6, ID(5), 4)); + +BEGIN + PROC2; +END; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index aed2839dd7ad..a801839043b9 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1039,7 +1039,7 @@ build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset, while (1) { tree fld; - tree tr_size, index; + tree tr_size, index, minidx; HOST_WIDE_INT el_size; if (offset == 0 && exp_type @@ -1090,13 +1090,14 @@ build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset, return false; el_size = tree_low_cst (tr_size, 1); + minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); + if (TREE_CODE (minidx) != INTEGER_CST) + return false; if (res) { index = build_int_cst (TYPE_DOMAIN (type), offset / el_size); - if (!integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (type)))) - index = int_const_binop (PLUS_EXPR, index, - TYPE_MIN_VALUE (TYPE_DOMAIN (type)), - 0); + if (!integer_zerop (minidx)) + index = int_const_binop (PLUS_EXPR, index, minidx, 0); *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index, NULL_TREE, NULL_TREE); } @@ -1378,6 +1379,22 @@ build_access_trees (struct access *access) } } +/* Return true if expr contains some ARRAY_REFs into a variable bounded + array. */ + +static bool +expr_with_var_bounded_array_refs_p (tree expr) +{ + while (handled_component_p (expr)) + { + if (TREE_CODE (expr) == ARRAY_REF + && !host_integerp (array_ref_low_bound (expr), 0)) + return true; + expr = TREE_OPERAND (expr, 0); + } + return false; +} + /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all sorts of access flags appropriately along the way, notably always ser @@ -1407,6 +1424,9 @@ analyze_access_subtree (struct access *root, bool allow_replacements, if (root->grp_unscalarizable_region) allow_replacements = false; + if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr)) + allow_replacements = false; + for (child = root->first_child; child; child = child->next_sibling) { if (!hole && child->offset < covered_to)