re PR middle-end/81695 (internal compiler error: in size_binop_loc, at fold-const...
authorMarek Polacek <polacek@redhat.com>
Fri, 4 Aug 2017 11:28:04 +0000 (11:28 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 4 Aug 2017 11:28:04 +0000 (11:28 +0000)
PR middle-end/81695
* fold-const.c (fold_indirect_ref_1): For ((int *)&a + 4 -> a[1],
perform the computation in offset_int.

* gcc.dg/pr81695.c: New test.

From-SVN: r250871

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr81695.c [new file with mode: 0644]

index c0d747dbcf2bcde77e7fbd8cb5a4e16c6f0835ee..811c9878d43e6a33111ccd88c674aba4cd249be1 100644 (file)
@@ -1,3 +1,9 @@
+2017-08-04  Marek Polacek  <polacek@redhat.com>
+
+       PR middle-end/81695
+       * fold-const.c (fold_indirect_ref_1): For ((int *)&a + 4 -> a[1],
+       perform the computation in offset_int.
+
 2017-08-04  Richard Sandiford  <richard.sandiford@linaro.org>
 
        PR tree-optimization/81136
index 53428b89454e766ab6f536f120b3424e596c0cb8..d563ba767668ddfcfbd2d0ea7c17550416d80b5b 100644 (file)
@@ -14107,14 +14107,21 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0)
                   && type == TREE_TYPE (op00type))
            {
              tree type_domain = TYPE_DOMAIN (op00type);
-             tree min_val = size_zero_node;
-             if (type_domain && TYPE_MIN_VALUE (type_domain))
-               min_val = TYPE_MIN_VALUE (type_domain);
-             op01 = size_binop_loc (loc, EXACT_DIV_EXPR, op01,
-                                    TYPE_SIZE_UNIT (type));
-             op01 = size_binop_loc (loc, PLUS_EXPR, op01, min_val);
-             return build4_loc (loc, ARRAY_REF, type, op00, op01,
-                                NULL_TREE, NULL_TREE);
+             tree min = TYPE_MIN_VALUE (type_domain);
+             if (min && TREE_CODE (min) == INTEGER_CST)
+               {
+                 offset_int off = wi::to_offset (op01);
+                 offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type));
+                 offset_int remainder;
+                 off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder);
+                 if (remainder == 0)
+                   {
+                     off = off + wi::to_offset (min);
+                     op01 = wide_int_to_tree (sizetype, off);
+                     return build4_loc (loc, ARRAY_REF, type, op00, op01,
+                                        NULL_TREE, NULL_TREE);
+                   }
+               }
            }
        }
     }
index 23f9c8fd16606e4fc4fbad0dabc33089badbad1f..fbb1fba0f5f8e8def604f656b01205e0ffa7be2d 100644 (file)
@@ -1,3 +1,8 @@
+2017-08-04  Marek Polacek  <polacek@redhat.com>
+
+       PR middle-end/81695
+       * gcc.dg/pr81695.c: New test.
+
 2017-08-04  Richard Sandiford  <richard.sandiford@linaro.org>
 
        PR tree-optimization/81136
diff --git a/gcc/testsuite/gcc.dg/pr81695.c b/gcc/testsuite/gcc.dg/pr81695.c
new file mode 100644 (file)
index 0000000..c345258
--- /dev/null
@@ -0,0 +1,11 @@
+/* PR middle-end/81695 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int z[] = { };
+
+int
+main (void)
+{
+  __builtin_printf ("%d\n", *(z + 1));
+}