]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-dfa.c (get_ref_base_and_extent): Do the offset computation using the precision...
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 7 May 2012 18:57:23 +0000 (18:57 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 7 May 2012 18:57:23 +0000 (18:57 +0000)
* tree-dfa.c (get_ref_base_and_extent) <ARRAY_REF>: Do the offset
computation using the precision of the index type.
* gimple-fold.c (fold_const_aggregate_ref_1) <ARRAY_REF>: Likewise.
(fold_array_ctor_reference): Do index computations in the index type.

From-SVN: r187268

gcc/ChangeLog
gcc/gimple-fold.c
gcc/tree-dfa.c

index 251edc671a95b47e925977130836d51f7940d350..09783656bf92ae6dd8343829f53b3e70bba5bd19 100644 (file)
@@ -1,4 +1,11 @@
-2012-05-07    Georg-Johann Lay  <avr@gjlay.de>
+2012-05-07  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree-dfa.c (get_ref_base_and_extent) <ARRAY_REF>: Do the offset
+       computation using the precision of the index type.
+       * gimple-fold.c (fold_const_aggregate_ref_1) <ARRAY_REF>: Likewise.
+       (fold_array_ctor_reference): Do index computations in the index type.
+
+2012-05-07  Georg-Johann Lay  <avr@gjlay.de>
 
        * config/avr/avr.c (avr_prologue_setup_frame): Fix mode passed
        down to plus_constant.
index 90405e67e0fdf57cdf3b0d7696e681b0d7b1ccad..55e7344043c19760dc3454d8c54cede82abefb4d 100644 (file)
@@ -2745,7 +2745,7 @@ fold_array_ctor_reference (tree type, tree ctor,
   double_int low_bound, elt_size;
   double_int index, max_index;
   double_int access_index;
-  tree domain_type = NULL_TREE;
+  tree domain_type = NULL_TREE, index_type = NULL_TREE;
   HOST_WIDE_INT inner_offset;
 
   /* Compute low bound and elt size.  */
@@ -2755,6 +2755,7 @@ fold_array_ctor_reference (tree type, tree ctor,
     {
       /* Static constructors for variably sized objects makes no sense.  */
       gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
+      index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type));
       low_bound = tree_to_double_int (TYPE_MIN_VALUE (domain_type));
     }
   else
@@ -2778,6 +2779,10 @@ fold_array_ctor_reference (tree type, tree ctor,
   access_index = double_int_udiv (uhwi_to_double_int (offset / BITS_PER_UNIT),
                                  elt_size, TRUNC_DIV_EXPR);
   access_index = double_int_add (access_index, low_bound);
+  if (index_type)
+    access_index = double_int_ext (access_index,
+                                  TYPE_PRECISION (index_type),
+                                  TYPE_UNSIGNED (index_type));
 
   /* And offset within the access.  */
   inner_offset = offset % (double_int_to_uhwi (elt_size) * BITS_PER_UNIT);
@@ -2788,6 +2793,11 @@ fold_array_ctor_reference (tree type, tree ctor,
     return NULL_TREE;
 
   index = double_int_sub (low_bound, double_int_one);
+  if (index_type)
+    index = double_int_ext (index,
+                           TYPE_PRECISION (index_type),
+                           TYPE_UNSIGNED (index_type));
+
   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
     {
       /* Array constructor might explicitely set index, or specify range
@@ -2805,7 +2815,14 @@ fold_array_ctor_reference (tree type, tree ctor,
            }
        }
       else
-       max_index = index = double_int_add (index, double_int_one);
+       {
+         index = double_int_add (index, double_int_one);
+         if (index_type)
+           index = double_int_ext (index,
+                                   TYPE_PRECISION (index_type),
+                                   TYPE_UNSIGNED (index_type));
+         max_index = index;
+       }
 
       /* Do we have match?  */
       if (double_int_cmp (access_index, index, 1) >= 0
@@ -2960,18 +2977,23 @@ fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree))
       if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
          && valueize
          && (idx = (*valueize) (TREE_OPERAND (t, 1)))
-         && host_integerp (idx, 0))
+         && TREE_CODE (idx) == INTEGER_CST)
        {
          tree low_bound, unit_size;
+         double_int doffset;
 
          /* If the resulting bit-offset is constant, track it.  */
          if ((low_bound = array_ref_low_bound (t),
-              host_integerp (low_bound, 0))
+              TREE_CODE (low_bound) == INTEGER_CST)
              && (unit_size = array_ref_element_size (t),
-                 host_integerp (unit_size, 1)))
+                 host_integerp (unit_size, 1))
+             && (doffset = double_int_sext
+                           (double_int_sub (TREE_INT_CST (idx),
+                                            TREE_INT_CST (low_bound)),
+                            TYPE_PRECISION (TREE_TYPE (idx))),
+                 double_int_fits_in_shwi_p (doffset)))
            {
-             offset = TREE_INT_CST_LOW (idx);
-             offset -= TREE_INT_CST_LOW (low_bound);
+             offset = double_int_to_shwi (doffset);
              offset *= TREE_INT_CST_LOW (unit_size);
              offset *= BITS_PER_UNIT;
 
index 0ecec816b6a67b812853c152f340fc2a23dcb721..3494fc9e962097512dec6d77cd61371d1f5352fe 100644 (file)
@@ -814,21 +814,24 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
          {
            tree index = TREE_OPERAND (exp, 1);
            tree low_bound, unit_size;
+           double_int doffset;
 
            /* If the resulting bit-offset is constant, track it.  */
            if (TREE_CODE (index) == INTEGER_CST
-               && host_integerp (index, 0)
                && (low_bound = array_ref_low_bound (exp),
-                   host_integerp (low_bound, 0))
+                   TREE_CODE (low_bound) == INTEGER_CST)
                && (unit_size = array_ref_element_size (exp),
-                   host_integerp (unit_size, 1)))
+                   host_integerp (unit_size, 1))
+               && (doffset = double_int_sext
+                             (double_int_sub (TREE_INT_CST (index),
+                                              TREE_INT_CST (low_bound)),
+                              TYPE_PRECISION (TREE_TYPE (index))),
+                   double_int_fits_in_shwi_p (doffset)))
              {
-               HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
-
-               hindex -= TREE_INT_CST_LOW (low_bound);
-               hindex *= TREE_INT_CST_LOW (unit_size);
-               hindex *= BITS_PER_UNIT;
-               bit_offset += hindex;
+               HOST_WIDE_INT hoffset = double_int_to_shwi (doffset);
+               hoffset *= TREE_INT_CST_LOW (unit_size);
+               hoffset *= BITS_PER_UNIT;
+               bit_offset += hoffset;
 
                /* An array ref with a constant index up in the structure
                   hierarchy will constrain the size of any variable array ref