aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/opt/stack1.C
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/g++.dg/opt/stack1.C')
-rw-r--r--gcc/testsuite/g++.dg/opt/stack1.C135
1 files changed, 135 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/opt/stack1.C b/gcc/testsuite/g++.dg/opt/stack1.C
new file mode 100644
index 00000000000..bb6159c568e
--- /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;
+}