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 <ja...@redhat.com> 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)); /* 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