diff options
author | Alan Lawrence <alan.lawrence@arm.com> | 2015-11-06 13:48:32 +0000 |
---|---|---|
committer | Alan Lawrence <alalaw01@gcc.gnu.org> | 2015-11-06 13:48:32 +0000 |
commit | 55bf45c0f38c819ffa4043593b97093a52dd5e53 (patch) | |
tree | 616cf403c591e4ceb7aaf76bcd8e77e640ab68a6 | |
parent | f1aa4bb328a5e69e93f33d1a9f3cb8969ab4bbd8 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/tree-sra.c | 23 |
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; |