On Thu, Oct 29, 2015 at 8:18 PM, Alan Lawrence <[email protected]> wrote:
> 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));
I think you want to use wide-ints here and
wide_int idx = wi::from (minidx, TYPE_PRECISION (TYPE_DOMAIN
(...)), TYPE_SIGN (TYPE_DOMAIN (..)));
wide_int maxidx = ...
you can then simply iterate minidx with ++ and do the final compare
against maxidx
with while (++idx <= maxidx). For the array ref index we want to use
TYPE_DOMAIN
as type as well, not size_int. Thus wide_int_to_tree (TYPE_DOMAIN (...)..idx).
RIchard.
> + 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
>