aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-08-13 09:39:50 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-08-13 09:39:50 +0000
commit310d5e7d8ce98f214ba4d83c4fd336f2a82565a2 (patch)
tree8944fccac960f218c34750d0637b8cf35ca65c95 /gcc
parentd27555bfeeb3f58037d5d399df5ae22c7c90d3fa (diff)
downloadgcc-310d5e7d8ce98f214ba4d83c4fd336f2a82565a2.zip
gcc-310d5e7d8ce98f214ba4d83c4fd336f2a82565a2.tar.gz
gcc-310d5e7d8ce98f214ba4d83c4fd336f2a82565a2.tar.bz2
re PR tree-optimization/67191 (ICE: in before_dom_children, at tree-ssa-sccvn.c:4372)
2015-08-13 Richard Biener <rguenther@suse.de> PR tree-optimization/67191 * tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children): Remove assert we value-numbered last stmts operand because it can validly trigger for unreachable code. * gcc.dg/torture/pr67191.c: New testcase. * g++.dg/torture/pr67191.C: Likewise. From-SVN: r226854
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/torture/pr67191.C117
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr67191.c13
-rw-r--r--gcc/tree-ssa-sccvn.c12
5 files changed, 147 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a677510..e06330d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-08-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/67191
+ * tree-ssa-sccvn.c (sccvn_dom_walker::before_dom_children): Remove
+ assert we value-numbered last stmts operand because it can validly
+ trigger for unreachable code.
+
2015-08-13 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR rtl-optimization/67103
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 79d408e..c3a9ff1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2015-08-13 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/67191
+ * gcc.dg/torture/pr67191.c: New testcase.
+ * g++.dg/torture/pr67191.C: Likewise.
+
+2015-08-13 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/66502
PR tree-optimization/67167
* gcc.dg/tree-ssa/ssa-fre-46.c: New testcase.
diff --git a/gcc/testsuite/g++.dg/torture/pr67191.C b/gcc/testsuite/g++.dg/torture/pr67191.C
new file mode 100644
index 0000000..79ee988
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr67191.C
@@ -0,0 +1,117 @@
+// { dg-do compile }
+
+template <typename> class A;
+template <typename _Tp> using __allocator_base = _Tp;
+template <class T, class = T, class = int, class = __allocator_base<int>>
+class B;
+template <class T, class H, class P, class A>
+bool operator==(B<T, H, P, A> const &, B<T, H, P, A> const &);
+template <class T, class H, class P, class A>
+bool operator!=(B<T, H, P, A> const &, B<T, H, P, A> const &);
+typedef B<int> int_multiset;
+int a;
+template <typename> struct C {
+ C(int) {}
+};
+template <typename> struct D;
+template <typename> struct K;
+struct L : C<A<D<int>>>, C<A<K<int>>> {
+ template <typename First, typename Second>
+ L(First, Second)
+ : C<A<D<int>>>(0), C<A<K<int>>>(0) {}
+};
+template <typename Node> struct F {
+ typedef typename Node::node_pointer node_pointer;
+ node_pointer node_;
+ F();
+ F(typename Node::link_pointer p1) : node_(static_cast<node_pointer>(p1)) {}
+ void operator++() { node_ = 0; }
+ int operator!=(F p1) { return node_ != p1.node_; }
+};
+struct G {
+ typedef G *link_pointer;
+};
+struct H {
+ static int new_bucket_count(int) {
+ int b;
+ int *c = 0;
+ if (a)
+ b = *c;
+ return b;
+ }
+};
+class functions {
+public:
+ functions(int, int) {}
+ ~functions();
+};
+template <typename Types> struct table : functions {
+ typedef typename Types::policy policy;
+ typedef Types node_allocator;
+ typedef F<typename Types::node> iterator;
+ L allocators_;
+ int bucket_count_;
+ int size_;
+ typename Types::link_pointer get_previous_start() const;
+ iterator begin() const { return size_ ? get_previous_start() : 0; }
+ table(int, typename Types::hasher, typename Types::key_equal, node_allocator)
+ : functions(0, 0), allocators_(0, 0),
+ bucket_count_(policy::new_bucket_count(0)), size_() {}
+};
+template <typename> struct K : G { typedef K *node_pointer; };
+struct I {
+ typedef G *link_pointer;
+};
+struct J {
+ typedef I::link_pointer link_pointer;
+};
+template <typename> struct D {
+ typedef int hasher;
+ typedef int key_equal;
+ typedef K<int> node;
+ typedef J::link_pointer link_pointer;
+ typedef H policy;
+};
+struct M : table<D<int>> {
+ node_allocator grouped_table_impl_a;
+ M(int, int) : table(0, 0, 0, grouped_table_impl_a) {}
+ void equals(M const &) const {
+ for (iterator d = begin(); d.node_;) {
+ iterator e;
+ group_equals(e);
+ }
+ }
+ static int group_equals(iterator p1) {
+ int f;
+ iterator g;
+ for (; g != p1; ++g)
+ if (find())
+ if (f)
+ return 0;
+ }
+ static int find();
+};
+template <class, class, class, class> class B {
+ M table_;
+
+public:
+ B(unsigned long = 0);
+ friend bool operator==<>(B const &, B const &);
+ friend bool operator!=<>(B const &, B const &);
+};
+template <class T, class H, class P, class A>
+B<T, H, P, A>::B(unsigned long)
+ : table_(0, 0) {}
+ template <class T, class H, class P, class A>
+ bool operator==(B<T, H, P, A> const &p1, B<T, H, P, A> const &p2) {
+ p1.table_.equals(p2.table_);
+ }
+template <class T, class H, class P, class A>
+bool operator!=(B<T, H, P, A> const &p1, B<T, H, P, A> const &p2) {
+ p1.table_.equals(p2.table_);
+}
+void use_multiset_fwd_declared_function_typerun() {
+ int_multiset x, y;
+ x == y;
+ x != y;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr67191.c b/gcc/testsuite/gcc.dg/torture/pr67191.c
new file mode 100644
index 0000000..b8623ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr67191.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+int a;
+void f(void)
+{
+ int b;
+ for(a=1; a;);
+ for(; b; b++)
+ lbl:
+ b || a;
+ if(a)
+ goto lbl;
+}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 73d1070..d4c2b46 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -4429,6 +4429,9 @@ sccvn_dom_walker::before_dom_children (basic_block bb)
return;
}
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Visiting BB %d\n", bb->index);
+
/* If we have a single predecessor record the equivalence from a
possible condition on the predecessor edge. */
if (single_pred_p (bb))
@@ -4502,17 +4505,10 @@ sccvn_dom_walker::before_dom_children (basic_block bb)
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "Visiting stmt ending BB %d: ", bb->index);
+ fprintf (dump_file, "Visiting control stmt ending BB %d: ", bb->index);
print_gimple_stmt (dump_file, stmt, 0, 0);
}
- /* Value-number the last stmts SSA uses. */
- ssa_op_iter i;
- tree op;
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
- gcc_assert (VN_INFO (op)->visited
- || SSA_NAME_IS_DEFAULT_DEF (op));
-
/* ??? We can even handle stmts with outgoing EH or ABNORMAL edges
if value-numbering can prove they are not reachable. Handling
computed gotos is also possible. */