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

Reply via email to