diff options
author | Richard Biener <rguenther@suse.de> | 2015-08-13 09:39:50 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-08-13 09:39:50 +0000 |
commit | 310d5e7d8ce98f214ba4d83c4fd336f2a82565a2 (patch) | |
tree | 8944fccac960f218c34750d0637b8cf35ca65c95 /gcc | |
parent | d27555bfeeb3f58037d5d399df5ae22c7c90d3fa (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr67191.C | 117 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr67191.c | 13 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 12 |
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. */ |