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