aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2003-07-07 07:25:36 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2003-07-07 07:25:36 +0000
commit82d610ec12da80bb3dc413ddad13ba142bbb99ad (patch)
tree5fff45cca9b698baed174e43aec9e69d95e5845a /gcc
parent5fc521ac46f693a6322389f7e24927e59e947ab6 (diff)
downloadgcc-82d610ec12da80bb3dc413ddad13ba142bbb99ad.zip
gcc-82d610ec12da80bb3dc413ddad13ba142bbb99ad.tar.gz
gcc-82d610ec12da80bb3dc413ddad13ba142bbb99ad.tar.bz2
re PR rtl-optimization/11198 (-O2 -frename-registers generates wrong code)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/alias.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/opt/stack1.C135
4 files changed, 157 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5296e65..5ba3038 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/alias.c b/gcc/alias.c
index c68a0ad..2617c8b 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -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;
}
/* T is an expression with pointer type. Find the DECL on which this
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3d067f5..683cb29 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..bb6159c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/stack1.C
@@ -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;
+}