On January 30, 2017 7:10:07 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>Hi!
>
>This is yet another occurrence of the bug that we drop lhs on noreturn
>calls even when it actually should not be dropped (if it has
>addressable
>type or if it is a variable length type).
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

>2017-01-30  Jakub Jelinek  <ja...@redhat.com>
>
>       PR tree-optimization/79267
>       * value-prof.c (gimple_ic): Only drop lhs for noreturn calls
>       if should_remove_lhs_p is true.
>
>       * g++.dg/opt/pr79267.C: New test.
>
>--- gcc/value-prof.c.jj        2017-01-01 12:45:38.000000000 +0100
>+++ gcc/value-prof.c   2017-01-30 12:30:47.179820533 +0100
>@@ -1358,7 +1358,8 @@ gimple_ic (gcall *icall_stmt, struct cgr
>   dcall_stmt = as_a <gcall *> (gimple_copy (icall_stmt));
>   gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
>   dflags = flags_from_decl_or_type (direct_call->decl);
>-  if ((dflags & ECF_NORETURN) != 0)
>+  if ((dflags & ECF_NORETURN) != 0
>+      && should_remove_lhs_p (gimple_call_lhs (dcall_stmt)))
>     gimple_call_set_lhs (dcall_stmt, NULL_TREE);
>   gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
> 
>--- gcc/testsuite/g++.dg/opt/pr79267.C.jj      2017-01-30 12:36:07.605516857
>+0100
>+++ gcc/testsuite/g++.dg/opt/pr79267.C 2017-01-30 12:35:51.000000000
>+0100
>@@ -0,0 +1,69 @@
>+// PR tree-optimization/79267
>+// { dg-do compile }
>+// { dg-options "-O3" }
>+
>+struct A { A (int); };
>+struct B
>+{
>+  virtual void av () = 0;
>+  void aw ();
>+  void h () { av (); aw (); }
>+};
>+template <class T> struct G : B
>+{
>+  T ba;
>+  G (int, T) : ba (0) {}
>+  void av () { ba (0); }
>+};
>+struct I
>+{
>+  B *bc;
>+  template <class j, class T> I (j, T) try { G<T> (0, 0); } catch
>(...) {}
>+  ~I () { bc->h (); }
>+};
>+template <class M> struct C { typedef M *i; };
>+template <class M> struct J
>+{
>+  J ();
>+  template <class O, class T> J (O, T p2) : be (0, p2) {}
>+  typename C<M>::i operator-> ();
>+  I be;
>+};
>+struct H : A { H () : A (0) {} };
>+struct D { J<int> d; void q (); };
>+template <typename = int> class bs;
>+int z;
>+
>+void
>+foo (int p1, int *, int)
>+{
>+  if (p1 == 0)
>+    throw H ();
>+}
>+
>+D bar ();
>+template <typename T> struct L
>+{
>+  struct K { K (int); void operator() (int *) { bar ().q (); } };
>+  static J<T> bp () { bq (0); }
>+  template <typename br> static void bq (br) { J<T> (0, K (0)); }
>+};
>+struct F
>+{
>+  virtual J<int> x (int) { foo (0, 0, 0); J<bs<> > (L<bs<> >::bp ());
>}
>+};
>+
>+void
>+baz ()
>+{
>+  if (z)
>+    {
>+      J<F> d, e;
>+      d->x (0);
>+      e->x (0);
>+    }
>+  J<F> v, i, j;
>+  v->x (0);
>+  i->x (0);
>+  j->x (0);
>+}
>
>       Jakub

Reply via email to