On Thu, 7 Feb 2019, Jakub Jelinek wrote:
> Hi!
>
> As mentioned in the PR, given that during expansion we expand ARRAY_REFs
> using get_inner_reference that casts ARRAY_*REF indexes to sizetype, all the
> bits above sizetype are ignored (whether one uses long long indexes on
> 32-bit targets or __int128 indexes on 64-bit ones), so I think it is
> desirable to make that visible already for GIMPLE optimizations, where we
> can narrow other arithmetic stmts feeding those indexes etc., it could help
> vectorization (e.g. gather/scatter), etc. Of course, fixing tree-data-ref.c
> etc. to cope with wider constants or chrecs is desirable as well.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2019-02-06 Jakub Jelinek <[email protected]>
>
> PR tree-optimization/89223
> * gimplify.c (gimplify_compound_lval): Narrow ARRAY*_REF indexes wider
> than sizetype to sizetype.
>
> * gcc.c-torture/execute/pr89223.c: New test.
>
> --- gcc/gimplify.c.jj 2019-01-28 23:30:53.199762928 +0100
> +++ gcc/gimplify.c 2019-02-06 17:15:35.368976785 +0100
> @@ -2977,6 +2977,12 @@ gimplify_compound_lval (tree *expr_p, gi
>
> if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
> {
> + /* Expansion will cast the index to sizetype, so any excess bits
> + aren't useful for optimizations. */
> + if (!error_operand_p (TREE_OPERAND (t, 1))
> + && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 1)))
> + > TYPE_PRECISION (sizetype)))
> + TREE_OPERAND (t, 1) = fold_convert (sizetype, TREE_OPERAND (t, 1));
Shouldn't we use ssizetype in case the index was signed (or always)?
I wonder what the effects are on SCEV-analyzability when the IV is, say
[unsigned] __int128 and the uses we analyze are then ([s]sizetype) IV
vs. plain IV. That is, I'm not sure exposing the casting on GIMPLE
is always a good idea. Did you look at how SCEV behaves with the change?
Otherwise I agree. Not sure if we want to do this during stage4 though.
Thanks,
Richard.
> /* Gimplify the dimension. */
> if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
> {
> --- gcc/testsuite/gcc.c-torture/execute/pr89223.c.jj 2019-02-07
> 18:09:39.869088769 +0100
> +++ gcc/testsuite/gcc.c-torture/execute/pr89223.c 2019-02-07
> 18:09:12.359543231 +0100
> @@ -0,0 +1,27 @@
> +/* PR tree-optimization/89223 */
> +/* { dg-do run { target int128 } } */
> +
> +int a[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
> +unsigned __int128 b;
> +
> +__attribute__((noipa)) void
> +foo (void)
> +{
> + for (b = (((unsigned __int128) 4) << 64) + 4; b != 0; b -= ((((unsigned
> __int128) 1) << 64) + 1))
> + a[b] = a[b + b];
> +}
> +
> +int
> +main ()
> +{
> + int i;
> + if (sizeof (__UINTPTR_TYPE__) * __CHAR_BIT__ != 64
> + || sizeof (__SIZE_TYPE__) * __CHAR_BIT__ != 64
> + || sizeof (__int128) * __CHAR_BIT__ != 128)
> + return 0;
> + foo ();
> + for (i = 0; i < 9; ++i)
> + if (a[i] != (((1 << i) & 0x16) != 0 ? 9 : i == 3 ? 7 : i + 1))
> + __builtin_abort ();
> + return 0;
> +}
>
> Jakub
>
>
--
Richard Biener <[email protected]>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB
21284 (AG Nuernberg)