Hi,
PR71281 happens when we use factored out negate stmt in other
reassociations. Since we don't set the uid for this stmt, we hit the
gcc_assert (in reassoc_stmt_dominates_stmt_p) which checks for uid being
set. Attached patch fixes this.
Regression tested on x86-64-linux-gnu with no new regression. Is this OK
for trunk?
Thanks,
Kugan
gcc/ChangeLog:
2016-06-04 Kugan Vivekanandarajah <kug...@linaro.org>
PR middle-end/71281
* tree-ssa-reassoc.c (reassociate_bb): Set uid for negate stmt.
gcc/testsuite/ChangeLog:
2016-06-04 Kugan Vivekanandarajah <kug...@linaro.org>
PR middle-end/71281
* g++.dg/torture/pr71281.C: New test.
diff --git a/gcc/testsuite/g++.dg/torture/pr71281.C
b/gcc/testsuite/g++.dg/torture/pr71281.C
index e69de29..7d429a9 100644
--- a/gcc/testsuite/g++.dg/torture/pr71281.C
+++ b/gcc/testsuite/g++.dg/torture/pr71281.C
@@ -0,0 +1,63 @@
+// PR middle-end/71281
+// { dg-do compile }
+// { dg-additional-options "-std=c++11 -Ofast" }
+
+
+template <typename> struct A;
+template <typename _Tp> struct A<_Tp *> { typedef _Tp reference; };
+
+template <typename _Iterator> class B {
+public:
+ typename A<_Iterator>::reference operator*();
+};
+
+template <typename> class C;
+template <typename> struct D;
+
+template <typename _Tp> struct D<C<_Tp>> {
+ using value_type = _Tp;
+ using const_pointer = _Tp *;
+ template <typename _Up> using rebind_alloc = C<_Up>;
+};
+
+template <typename _Alloc> struct __alloc_traits : D<_Alloc> {
+ typedef D<_Alloc> _Base_type;
+ typedef typename _Base_type::value_type &reference;
+ template <typename _Tp> struct F {
+ typedef typename _Base_type::template rebind_alloc<_Tp> other;
+ };
+};
+
+template <typename _Tp, typename _Alloc> struct G {
+ typedef typename __alloc_traits<_Alloc>::template F<_Tp>::other
+ _Tp_alloc_type;
+};
+
+int a, b;
+long d[1][1][1];
+void fn1() __attribute__((__noreturn__));
+template <typename _Tp, typename _Alloc = C<_Tp>> class H {
+ typedef __alloc_traits<typename G<_Tp, _Alloc>::_Tp_alloc_type>
_Alloc_traits;
+ typedef typename _Alloc_traits::reference reference;
+
+public:
+ B<typename _Alloc_traits::const_pointer> m_fn1();
+ long m_fn2();
+ reference operator[](unsigned);
+ reference m_fn3(unsigned){
+ if (m_fn2())
+ fn1();
+ }
+};
+
+H<H<H<unsigned>>> c;
+void fn2() {
+ H<unsigned, C<int>> e;
+ for (int f = 1;;)
+ for (int g = 0;;)
+ for (int h = 0;;)
+ {
+ *d[0][h] =
+ c.m_fn3(f)[0][g] * a + -*(e).m_fn1() * b +
(*c[f].m_fn1()).m_fn3(g);
+ }
+}
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 1973077..096b24d 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -5387,6 +5387,7 @@ reassociate_bb (basic_block bb)
gimple_set_lhs (stmt, tmp);
gassign *neg_stmt = gimple_build_assign (lhs, NEGATE_EXPR,
tmp);
+ gimple_set_uid (neg_stmt, gimple_uid (stmt));
gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
gsi_insert_after (&gsi, neg_stmt, GSI_NEW_STMT);
update_stmt (stmt);