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

Reply via email to