]> gcc.gnu.org Git - gcc.git/commitdiff
re PR rtl-optimization/11198 (-O2 -frename-registers generates wrong code)
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Mon, 7 Jul 2003 07:25:36 +0000 (07:25 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 7 Jul 2003 07:25:36 +0000 (07:25 +0000)
PR optimization/11198
* alias.c (objects_must_conflict_p): Return 1 if the types have
the same alias set, not if the alias sets only conflict.

Co-Authored-By: Eric Botcazou <ebotcazou@libertysurf.fr>
From-SVN: r69034

gcc/ChangeLog
gcc/alias.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/stack1.C [new file with mode: 0644]

index 5296e65fb68e2fa42c05b97573e8a58603a43ae2..5ba3038c068d6909cfb70a6fdf863febaed2ca9e 100644 (file)
@@ -1,3 +1,10 @@
+2003-07-07  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+            Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR optimization/11198
+       * alias.c (objects_must_conflict_p): Return 1 if the types have
+       the same alias set, not if the alias sets only conflict.
+
 2003-07-07  Andrew Pinski  <pinskia@physics.uc.edu>
 
        * cppcharset.c (ICONV_CONST): Define iff !HAVE_ICONV.
index c68a0ad10b91e8d0c6494a9765292ca2016d9dd5..2617c8b5e710beb57f53c352f4f5061575c13a04 100644 (file)
@@ -317,6 +317,8 @@ readonly_fields_p (tree type)
 int
 objects_must_conflict_p (tree t1, tree t2)
 {
+  HOST_WIDE_INT set1, set2;
+
   /* If neither has a type specified, we don't know if they'll conflict
      because we may be using them to store objects of various types, for
      example the argument and local variables areas of inlined functions.  */
@@ -337,15 +339,15 @@ objects_must_conflict_p (tree t1, tree t2)
       || (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2)))
     return 1;
 
-  /* If one is aggregate and the other is scalar then they may not
-     conflict.  */
-  if ((t1 != 0 && AGGREGATE_TYPE_P (t1))
-      != (t2 != 0 && AGGREGATE_TYPE_P (t2)))
-    return 0;
+  set1 = t1 ? get_alias_set (t1) : 0;
+  set2 = t2 ? get_alias_set (t2) : 0;
 
-  /* Otherwise they conflict only if the alias sets conflict.  */
-  return alias_sets_conflict_p (t1 ? get_alias_set (t1) : 0,
-                               t2 ? get_alias_set (t2) : 0);
+  /* Otherwise they conflict if they have no alias set or the same. We
+     can't simply use alias_sets_conflict_p here, because we must make
+     sure that every subtype of t1 will conflict with every subtype of
+     t2 for which a pair of subobjects of these respective subtypes
+     overlaps on the stack.  */
+  return set1 == 0 || set2 == 0 || set1 == set2;
 }
 \f
 /* T is an expression with pointer type.  Find the DECL on which this
index 3d067f575e9e8f97e946a42b5961baa5108bce3c..683cb294952b3167fe4b279c523eb54638d35f5c 100644 (file)
@@ -1,3 +1,8 @@
+2003-07-07  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+            Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * g++.dg/opt/stack1.C: New test.
+
 2003-07-05  Mark Mitchell  <mark@codesourcery.com>
 
        * g++.old-deja/g++.jason/typeid1.C: Make it a compile test, not a
diff --git a/gcc/testsuite/g++.dg/opt/stack1.C b/gcc/testsuite/g++.dg/opt/stack1.C
new file mode 100644 (file)
index 0000000..bb6159c
--- /dev/null
@@ -0,0 +1,135 @@
+// PR optimization/11198
+// Origin: Joerg Walter <jhr.walter@t-online.de>
+// Reduced testcase by: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+//                      Wolfgang Bangerth <bangerth@ticam.utexas.edu>
+
+// The compiler used to allocate the same stack slot for two aggregates,
+// overlooking that assignments to members given the same address on the
+// stack may not alias and thus may be reordered by the scheduling passes.
+
+// { dg-do run }
+// { dg-options "-O2 -frename-registers" }
+
+
+double zero_;
+
+inline const int&
+min(const int& a, const int& b) {
+  if (b < a) return b; return a;
+}
+
+struct barrier { barrier () {} };
+
+template <typename=void> struct unbounded_array {
+    inline unbounded_array (): data_ (new double [9]) {}
+    inline double& operator [] (int i) { return data_ [i]; }
+    double* data_;
+};
+
+inline int element (int i, int j) {
+  return i + j;
+}
+
+template <typename=void>
+struct matrix {
+    inline matrix () : size2_ (3) {}
+
+    inline unbounded_array<> &data () { return data_; }
+
+    inline double& el (int i, int j) {
+      int dead1 = j;
+      int dead2 = 1 + i - j;
+      if (j < size2_ && i-j < 2)
+       return data () [element (j,i-j+1)];
+      barrier ();
+      return zero_;
+    }
+
+    struct iterator2;
+
+    inline iterator2 find () {
+      return iterator2 (*this);
+    }
+
+    struct iterator1 {
+        inline iterator1 (matrix *m):
+                       dead1 (m), i (0) {}
+       void *dead1;
+        int i;
+        int dead2;
+    };
+
+    const int size2_;
+    unbounded_array<> data_;
+};
+
+
+template<typename=void>
+struct adaptor {
+    adaptor (matrix<> &m) : m(&m), upper_ (1) {}
+
+    int size1 () const     { return m->size1 (); }
+    int size2 () const     { return 3; }
+    int lower () const     { return 1; }
+    int upper () const     { return upper_; }
+    matrix<> &data () { return *m; }
+
+    double& el (int i, int j) {
+      int dead1, dead2;
+      if (j < size2 () && i-j < 1)
+       return data ().el (i, j);
+
+      barrier ();
+      return zero_;
+    }
+
+    struct a_iterator2;
+
+    struct a_iterator1 {
+        a_iterator1 (adaptor &a, const matrix<>::iterator1 &it1):
+                       a (&a), dead1 (it1) {}
+
+        a_iterator2 begin () const {
+         return a_iterator2(*a);
+        }
+       adaptor *a;     
+        matrix<>::iterator1 dead1;
+    };
+
+    struct a_iterator2 {
+        a_iterator2 (adaptor &a) : a (&a) {}
+
+        double& f () const {
+         int i = 0;
+         int l = a->upper () + i;
+         int q = a->size2 ();
+         if (0 < q &&
+             l < a->lower () + 1 + a->upper ())
+           return a->m->el(0,0);
+
+         return a->el (i, 0);
+        }
+
+       adaptor *a;
+    };
+
+    matrix<> *m;
+    int upper_;
+};
+
+void matrix_swap (adaptor<> &bam1, adaptor<> &bam2)
+{
+  adaptor<>::a_iterator1 it1 (bam1,matrix<>::iterator1(bam1.m)),
+                         it2 (bam2,matrix<>::iterator1(bam2.m));
+  int dead;
+  double x = it1.begin().f();
+  it2.begin().f() = x;
+}
+
+int main ()
+{
+  matrix<> m1,m2;
+  adaptor<> bam1 (m1), bam2 (m2);
+  matrix_swap (bam1, bam2);
+  return 0;
+}
This page took 0.120546 seconds and 5 git commands to generate.