aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Lawrence <alan.lawrence@arm.com>2015-11-06 13:48:32 +0000
committerAlan Lawrence <alalaw01@gcc.gnu.org>2015-11-06 13:48:32 +0000
commit55bf45c0f38c819ffa4043593b97093a52dd5e53 (patch)
tree616cf403c591e4ceb7aaf76bcd8e77e640ab68a6
parentf1aa4bb328a5e69e93f33d1a9f3cb8969ab4bbd8 (diff)
downloadgcc-55bf45c0f38c819ffa4043593b97093a52dd5e53.zip
gcc-55bf45c0f38c819ffa4043593b97093a52dd5e53.tar.gz
gcc-55bf45c0f38c819ffa4043593b97093a52dd5e53.tar.bz2
tree-sra.c: Fix completely_scalarize for negative indices.
* tree-sra.c (completely_scalarize): Properly handle negative array indices using offset_int. From-SVN: r229852
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/tree-sra.c23
2 files changed, 20 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6b499dd..219b6c9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 2ddc934..1d4a632 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -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;