aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-16 13:21:11 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-16 13:21:11 +0000
commitb6d76e6809aa0b50b2ecb1c591fa021efc69e3d7 (patch)
treece8ca9cf40876e7e528d54e27b6478f01da17163
parent15b4214cd08beb74ad09bf07e8c194bb16b59a5a (diff)
2015-01-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/64568 * tree-ssa-forwprop.c (pass_forwprop::execute): Guard complex load rewriting for TARGET_MEM_REFs. * g++.dg/torture/pr64568-2.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219736 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr64568-2.C146
-rw-r--r--gcc/tree-ssa-forwprop.c2
4 files changed, 159 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4010ace26a6..c9a70702d52 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/64568
+ * tree-ssa-forwprop.c (pass_forwprop::execute): Guard
+ complex load rewriting for TARGET_MEM_REFs.
+
2015-01-16 Uros Bizjak <ubizjak@gmail.com>
* builtins.c (expand_builtin_acc_on_device): Check target for NULL.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6da9eee4d23..81645b11cae 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-01-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/64568
+ * g++.dg/torture/pr64568-2.C: New testcase.
+
2015-01-16 Ilya Enkovich <ilya.enkovich@intel.com>
PR target/64363
diff --git a/gcc/testsuite/g++.dg/torture/pr64568-2.C b/gcc/testsuite/g++.dg/torture/pr64568-2.C
new file mode 100644
index 00000000000..05782179008
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr64568-2.C
@@ -0,0 +1,146 @@
+// { dg-do compile }
+
+namespace std
+{
+ typedef __SIZE_TYPE__ size_t;
+}
+class H;
+namespace std
+{
+ template <typename> struct complex;
+ template <typename _Tp>
+ complex<_Tp> operator+(complex<_Tp> &__x, complex<_Tp> __y)
+ {
+ complex<_Tp> a = __x;
+ a += __y;
+ return a;
+ }
+ template <> struct complex<double>
+ {
+ int
+ imag ()
+ {
+ return __imag__ _M_value;
+ }
+ void operator+=(complex __z) { _M_value += _M_value; _M_value += __z.imag (); }
+ _Complex double _M_value;
+ };
+}
+struct A
+{
+ typedef std::complex<double> &const_reference;
+};
+class B
+{
+public:
+ B (int);
+ std::complex<double> &operator[](int i) { return data_[i]; }
+ std::complex<double> *data_;
+};
+struct C
+{
+ static std::complex<double>
+ apply (A::const_reference t1, std::complex<double> t2)
+ {
+ return t1 + t2;
+ }
+ typedef std::complex<double> result_type;
+};
+template <class T1, class> struct D
+{
+ static void
+ apply (T1 t1, std::complex<double> t2)
+ {
+ t1 = t2;
+ }
+};
+class ublas_expression
+{
+public:
+ ~ublas_expression ();
+};
+template <class> class F
+{
+};
+template <class E> class matrix_expression : ublas_expression
+{
+public:
+ E &operator()() {}
+};
+class I : public F<int>
+{
+public:
+ typedef int value_type;
+ I (int);
+};
+template <class E1, class E2> matrix_expression<int> outer_prod (F<E1>, F<E2>);
+template <class E1, class F> class J : public matrix_expression<J<E1, F> >
+{
+public:
+ typedef typename F::result_type value_type;
+ value_type operator()(int i, int)
+ {
+ return F::apply (e1_ (i, 0), e2_ (0, 0));
+ }
+ E1 e1_;
+ E1 e2_;
+};
+template <class E1, class E2>
+J<H, C> operator+(matrix_expression<E1>, matrix_expression<E2>);
+template <template <class, class> class F, class M, class E>
+void
+indexing_matrix_assign (M m, matrix_expression<E> e, int)
+{
+ for (int i; i; ++i)
+ F<typename M::reference, typename E::value_type>::apply (m (0, 0),
+ e ()(i, 0));
+}
+template <template <class, class> class F, class, class M, class E, class C>
+void
+matrix_assign (M m, matrix_expression<E> e, int, C)
+{
+ indexing_matrix_assign<F> (m, e, 0);
+}
+template <template <class, class> class F, class M, class E>
+void
+matrix_assign (M m, matrix_expression<E> e)
+{
+ matrix_assign<F, int> (m, e, 0, typename M::orientation_category ());
+}
+class H : matrix_expression<int>
+{
+public:
+ typedef std::complex<double> &reference;
+ typedef int orientation_category;
+ H (int, int) : data_ (0) {}
+ template <class AE> H (matrix_expression<AE> ae) : data_ (0)
+ {
+ matrix_assign<D> (*this, ae);
+ }
+ B &
+ data ()
+ {
+ }
+ std::complex<double> &operator()(int i, int) { return data ()[i]; }
+ void operator+=(matrix_expression ae) { H (*this + ae); }
+ B data_;
+};
+template <class M, class T, class V1, class V2>
+void
+sr2 (M m, T, V1 v1, V2 v2)
+{
+ m += outer_prod (v2, v1);
+}
+template <class, class, std::size_t> struct G
+{
+ void test ();
+};
+template struct G<I, H, 3>;
+template <class V, class M, std::size_t N>
+void
+G<V, M, N>::test ()
+{
+ V b (0), c (0);
+ M m (0, 0);
+ sr2 (m, typename V::value_type (), b, c);
+}
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index a4140e5e6ae..82d832d4754 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2230,6 +2230,8 @@ pass_forwprop::execute (function *fun)
else if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE
&& gimple_assign_load_p (stmt)
&& !gimple_has_volatile_ops (stmt)
+ && (TREE_CODE (gimple_assign_rhs1 (stmt))
+ != TARGET_MEM_REF)
&& !stmt_can_throw_internal (stmt))
{
/* Rewrite loads used only in real/imagpart extractions to