The code I added to completely_scalarize for arrays isn't right in some cases of negative array indices (e.g. arrays with indices from -1 to 1 in the Ada testsuite). On ARM, this prevents a failure bootstrapping Ada with the next patch, as well as a few ACATS tests (e.g. c64106a).
Some discussion here: https://gcc.gnu.org/ml/gcc/2015-10/msg00096.html . gcc/ChangeLog: * tree-sra.c (completely_scalarize): Deal properly with negative array indices. --- gcc/tree-sra.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index e15df1f..358db79 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1010,18 +1010,25 @@ completely_scalarize (tree base, tree decl_type, HOST_WIDE_INT offset, tree ref) if (maxidx) { gcc_assert (TREE_CODE (maxidx) == INTEGER_CST); - /* MINIDX and MAXIDX are inclusive. Try to avoid overflow. */ - unsigned HOST_WIDE_INT lenp1 = tree_to_shwi (maxidx) - - tree_to_shwi (minidx); + /* MINIDX and MAXIDX are inclusive, and must be interpreted in the + TYPE_DOMAIN (e.g. signed int, whereas min/max may be size_int). + Try also to avoid overflow. */ + minidx = build_int_cst (TYPE_DOMAIN (decl_type), + tree_to_shwi (minidx)); + maxidx = build_int_cst (TYPE_DOMAIN (decl_type), + tree_to_shwi (maxidx)); + HOST_WIDE_INT min = tree_to_shwi (minidx); + unsigned HOST_WIDE_INT lenlessone = tree_to_shwi (maxidx) - min; unsigned HOST_WIDE_INT idx = 0; do { - tree nref = build4 (ARRAY_REF, elemtype, ref, size_int (idx), + tree nref = build4 (ARRAY_REF, elemtype, + ref, size_int (idx + min), NULL_TREE, NULL_TREE); int el_off = offset + idx * el_size; scalarize_elem (base, el_off, el_size, nref, elemtype); } - while (++idx <= lenp1); + while (++idx <= lenlessone); } } break; -- 1.9.1