re PR tree-optimization/67191 (ICE: in before_dom_children, at tree-ssa-sccvn.c:4372)
authorRichard Biener <rguenther@suse.de>
Thu, 13 Aug 2015 09:39:50 +0000 (09:39 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 13 Aug 2015 09:39:50 +0000 (09:39 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr67191.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr67191.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index a677510789e2317fe719a944bc1dc7f678b0b2cb..e06330d384aef0ee51a1007722c2c4fc13017a63 100644 (file)
@@ -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
index 79d408e456381bcdea0ae445307db04f7112f80a..c3a9ff104ee3130b115e4915362d13ad1caf818b 100644 (file)
@@ -1,3 +1,9 @@
+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
diff --git a/gcc/testsuite/g++.dg/torture/pr67191.C b/gcc/testsuite/g++.dg/torture/pr67191.C
new file mode 100644 (file)
index 0000000..79ee988
--- /dev/null
@@ -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 (file)
index 0000000..b8623ef
--- /dev/null
@@ -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;
+}
index 73d1070df441611a3d731e664e86ce9107f0b850..d4c2b46316c863bd414993f838cee0deb13a413c 100644 (file)
@@ -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.  */