The following makes use of range-info to improve the basic building
block of the alias-oracle so we can tell that in

  a[0] = 1;
  for (int i = 5; i < 17; ++i)
    a[i] = i;
  a[0] = 2;

the ao_ref for a[i] does not alias the a[0] acceses.  Given range-info
is not always going to improve things over knowledge gained from
the type size of the access I'm only improving it over information
gathered from the size.

For the above this allows us to DSE the first store with another
DSE improvement I'm testing separately.

Bootstrap & regtest in progress on x86_64-unknown-linux-gnu.

Richard.

2018-05-17  Richard Biener  <rguent...@suse.de>

        * tree-dfa.c (get_ref_base_and_extent): Use range-info to refine
        results when processing array refs with variable index.

        * gcc.dg/tree-ssa/ssa-dse-35.c: New testcase.

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-35.c 
b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-35.c
new file mode 100644
index 00000000000..1f21670406f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-35.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dse1-details" } */
+
+int a[256];
+void foo (void)
+{
+  a[0] = 1;
+  for (int i = 5; i < 17; ++i)
+    a[i] = i;
+  a[0] = 2;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead store" 1 "dse1" } } */
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index a121b880bb0..993ac49554d 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -529,6 +529,48 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset,
                /* Remember that we have seen an array ref with a variable
                   index.  */
                seen_variable_array_ref = true;
+
+               wide_int min, max;
+               if (TREE_CODE (index) == SSA_NAME
+                   && (low_bound = array_ref_low_bound (exp),
+                       poly_int_tree_p (low_bound))
+                   && (unit_size = array_ref_element_size (exp),
+                       TREE_CODE (unit_size) == INTEGER_CST)
+                   && get_range_info (index, &min, &max) == VR_RANGE)
+                 {
+                   poly_offset_int lbound = wi::to_poly_offset (low_bound);
+                   /* Try to constrain maxsize with range information.  */
+                   offset_int omax
+                     = offset_int::from (max, TYPE_SIGN (TREE_TYPE (index)));
+                   if (known_lt (lbound, omax))
+                     {
+                       poly_offset_int rmaxsize;
+                       rmaxsize = (omax - lbound + 1)
+                           * wi::to_offset (unit_size) << LOG2_BITS_PER_UNIT;
+                       if (!known_size_p (maxsize)
+                           || known_lt (rmaxsize, maxsize))
+                         {
+                           maxsize = rmaxsize;
+                           /* Given we know an upper bound this is no
+                              longer variable.  */
+                           seen_variable_array_ref = false;
+                         }
+                     }
+                   /* Try to adjust bit_offset with range information.  */
+                   offset_int omin
+                     = offset_int::from (min, TYPE_SIGN (TREE_TYPE (index)));
+                   if (known_le (lbound, omin))
+                     {
+                       poly_offset_int woffset
+                         = wi::sext (omin - lbound,
+                                     TYPE_PRECISION (TREE_TYPE (index)));
+                       woffset *= wi::to_offset (unit_size);
+                       woffset <<= LOG2_BITS_PER_UNIT;
+                       bit_offset += woffset;
+                       if (known_size_p (maxsize))
+                         maxsize -= woffset;
+                     }
+                 }
              }
          }
          break;

Reply via email to