re PR rtl-optimization/48695 (Runtime with an array of std::vectors)
authorRichard Guenther <rguenther@suse.de>
Wed, 20 Apr 2011 13:11:06 +0000 (13:11 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 20 Apr 2011 13:11:06 +0000 (13:11 +0000)
2011-04-20  Richard Guenther  <rguenther@suse.de>

PR middle-end/48695
* tree-ssa-alias.c (aliasing_component_refs_p): Compute base
objects and types here.  Adjust for their offset before
comparing.

* g++.dg/torture/pr48695.C: New testcase.

From-SVN: r172768

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr48695.C [new file with mode: 0644]
gcc/tree-ssa-alias.c

index 5ff852bd001d090473eda02da695c48f5a1c629b..da88769f6ca2b80b1f7b84ffccecfafdfde34497 100644 (file)
@@ -1,3 +1,10 @@
+2011-04-20  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/48695
+       * tree-ssa-alias.c (aliasing_component_refs_p): Compute base
+       objects and types here.  Adjust for their offset before
+       comparing.
+
 2011-04-20  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * doc/md.texi, optabs.h, genopinit.c, internal-fn.def
index ac3e350c95ff6530d3dd58c942eda69c1486e3ce..a4b42d9b91b1b9c8a2f6c3ca7650a434a3812c17 100644 (file)
@@ -1,3 +1,8 @@
+2011-04-20  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/48695
+       * g++.dg/torture/pr48695.C: New testcase.
+
 2011-04-20  Georg-Johann Lay  <avr@gjlay.de>
 
        * gcc.dg/pr42629.c: Add dg-require-effective-target int32plus
diff --git a/gcc/testsuite/g++.dg/torture/pr48695.C b/gcc/testsuite/g++.dg/torture/pr48695.C
new file mode 100644 (file)
index 0000000..44e6c77
--- /dev/null
@@ -0,0 +1,38 @@
+// { dg-do run }
+
+typedef __SIZE_TYPE__ size_t;
+
+inline void *operator new (size_t, void *__p) throw() { return __p; }
+
+struct _Vector_impl
+{
+  int *_M_start;
+  int *_M_finish;
+  _Vector_impl () :_M_start (0), _M_finish (0) {}
+};
+
+struct vector
+{
+  _Vector_impl _M_impl;
+  int *_M_allocate (size_t __n)
+  {
+    return __n != 0 ? new int[__n] : 0;
+  }
+  void push_back ()
+  {
+    new (this->_M_impl._M_finish) int ();
+    this->_M_impl._M_finish =
+      this->_M_allocate (this->_M_impl._M_finish - this->_M_impl._M_start) + 1;
+  }
+};
+
+int
+main ()
+{
+  for (int i = 0; i <= 1; i++)
+    for (int j = 0; j <= 1; j++)
+      {
+       vector a[2];
+       a[i].push_back ();
+      }
+}
index 67ba8f1323cbed25b97a38ea580cf769e517128a..a77c803b98c08ed9fafd2f3fffbde81732aad227 100644 (file)
@@ -593,11 +593,11 @@ same_type_for_tbaa (tree type1, tree type2)
    are the respective alias sets.  */
 
 static bool
-aliasing_component_refs_p (tree ref1, tree type1,
+aliasing_component_refs_p (tree ref1,
                           alias_set_type ref1_alias_set,
                           alias_set_type base1_alias_set,
                           HOST_WIDE_INT offset1, HOST_WIDE_INT max_size1,
-                          tree ref2, tree type2,
+                          tree ref2,
                           alias_set_type ref2_alias_set,
                           alias_set_type base2_alias_set,
                           HOST_WIDE_INT offset2, HOST_WIDE_INT max_size2,
@@ -609,9 +609,21 @@ aliasing_component_refs_p (tree ref1, tree type1,
        struct A { int i; int j; } *q;
        struct B { struct A a; int k; } *p;
      disambiguating q->i and p->a.j.  */
+  tree base1, base2;
+  tree type1, type2;
   tree *refp;
   int same_p;
 
+  /* Choose bases and base types to search for.  */
+  base1 = ref1;
+  while (handled_component_p (base1))
+    base1 = TREE_OPERAND (base1, 0);
+  type1 = TREE_TYPE (base1);
+  base2 = ref2;
+  while (handled_component_p (base2))
+    base2 = TREE_OPERAND (base2, 0);
+  type2 = TREE_TYPE (base2);
+
   /* Now search for the type1 in the access path of ref2.  This
      would be a common base for doing offset based disambiguation on.  */
   refp = &ref2;
@@ -627,6 +639,8 @@ aliasing_component_refs_p (tree ref1, tree type1,
       HOST_WIDE_INT offadj, sztmp, msztmp;
       get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp);
       offset2 -= offadj;
+      get_ref_base_and_extent (base1, &offadj, &sztmp, &msztmp);
+      offset1 -= offadj;
       return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
     }
   /* If we didn't find a common base, try the other way around.  */
@@ -643,6 +657,8 @@ aliasing_component_refs_p (tree ref1, tree type1,
       HOST_WIDE_INT offadj, sztmp, msztmp;
       get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp);
       offset1 -= offadj;
+      get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp);
+      offset2 -= offadj;
       return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
     }
 
@@ -804,11 +820,10 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
       && TREE_CODE (base1) != TARGET_MEM_REF
       && (TREE_CODE (base1) != MEM_REF
          || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1))
-    return aliasing_component_refs_p (ref1, TREE_TYPE (ptrtype1),
+    return aliasing_component_refs_p (ref1,
                                      ref1_alias_set, base1_alias_set,
                                      offset1, max_size1,
-                                     ref2, TREE_TYPE
-                                             (reference_alias_ptr_type (ref2)),
+                                     ref2,
                                      ref2_alias_set, base2_alias_set,
                                      offset2, max_size2, true);
 
@@ -951,10 +966,10 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
          || same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1)
       && (TREE_CODE (base2) != MEM_REF
          || same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1))
-    return aliasing_component_refs_p (ref1, TREE_TYPE (ptrtype1),
+    return aliasing_component_refs_p (ref1,
                                      ref1_alias_set, base1_alias_set,
                                      offset1, max_size1,
-                                     ref2, TREE_TYPE (ptrtype2),
+                                     ref2,
                                      ref2_alias_set, base2_alias_set,
                                      offset2, max_size2, false);