tree-sra.c: Fix completely_scalarize for negative indices.
authorAlan Lawrence <alan.lawrence@arm.com>
Fri, 6 Nov 2015 13:48:32 +0000 (13:48 +0000)
committerAlan Lawrence <alalaw01@gcc.gnu.org>
Fri, 6 Nov 2015 13:48:32 +0000 (13:48 +0000)
* tree-sra.c (completely_scalarize): Properly handle negative array
indices using offset_int.

From-SVN: r229852

gcc/ChangeLog
gcc/tree-sra.c

index 6b499dd68b57dec7e8ad1a1e134a62659e4cafeb..219b6c95409a84f164187c27786b77f36d7daffc 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-06  Alan Lawrence  <alan.lawrence@arm.com>
+
+       * tree-sra.c (completely_scalarize): Properly handle negative array
+       indices using offset_int.
+
 2015-11-06  Richard Biener  <rguenther@suse.de>
 
        * alloc-pool.h (object_allocator::allocate): Default-initialize
index 2ddc9349aef55d764c3d3a2eb9eb9792e31815b9..1d4a632dc432cb9b17ab43aa8a65f3738d0e02db 100644 (file)
@@ -999,18 +999,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);
-           unsigned HOST_WIDE_INT idx = 0;
-           do
+           tree domain = TYPE_DOMAIN (decl_type);
+           /* MINIDX and MAXIDX are inclusive, and must be interpreted in
+              DOMAIN (e.g. signed int, whereas min/max may be size_int).  */
+           offset_int idx = wi::to_offset (minidx);
+           offset_int max = wi::to_offset (maxidx);
+           if (!TYPE_UNSIGNED (domain))
              {
-               tree nref = build4 (ARRAY_REF, elemtype, ref, size_int (idx),
+               idx = wi::sext (idx, TYPE_PRECISION (domain));
+               max = wi::sext (max, TYPE_PRECISION (domain));
+             }
+           for (int el_off = offset; wi::les_p (idx, max); ++idx)
+             {
+               tree nref = build4 (ARRAY_REF, elemtype,
+                                   ref,
+                                   wide_int_to_tree (domain, idx),
                                    NULL_TREE, NULL_TREE);
-               int el_off = offset + idx * el_size;
                scalarize_elem (base, el_off, el_size, nref, elemtype);
+               el_off += el_size;
              }
-           while (++idx <= lenp1);
          }
       }
       break;