Commit 310d5e7d by Richard Biener Committed by Richard Biener

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
parent d27555bf
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
......
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.
......
// { 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;
}
/* { dg-do compile } */
int a;
void f(void)
{
int b;
for(a=1; a;);
for(; b; b++)
lbl:
b || a;
if(a)
goto lbl;
}
......@@ -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. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment