Message ID | 20160211161416.GC3017@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On Thu, 11 Feb 2016, Jakub Jelinek wrote: > On Thu, Feb 11, 2016 at 10:22:24AM +0100, Richard Biener wrote: > > The other option is to simply not split the function in this case. > > Here is a better fix (but it needs the other patch I've sent, so that > what is return_bb stays the same). > > This patch arranges for the case where there is return_bb, but does not > return a value, in function that has return type TREE_ADDRESSABLE, > to just use void return type from the split part (because we would never > set lhs of the call to *.part.* in that case anyway). > > Bootstrapped/regtested on x86_64-linux and i686-linux on top of the PR68672 > patch, ok for trunk? Ok. Thanks, Richard. > 2016-02-10 Jakub Jelinek <jakub@redhat.com> > > PR ipa/69241 > * ipa-split.c (split_function): If split part returns TREE_ADDRESSABLE > type by reference, force lhs on the call. > > * g++.dg/ipa/pr69241-4.C: New test. > > --- gcc/ipa-split.c.jj 2016-02-11 12:46:15.975777652 +0100 > +++ gcc/ipa-split.c 2016-02-11 13:06:57.715241871 +0100 > @@ -629,7 +629,18 @@ consider_split (struct split_point *curr > 4) For non-SSA we need to look where the var is computed. */ > retval = find_retval (return_bb); > if (!retval) > - current->split_part_set_retval = true; > + { > + /* If there is a return_bb with no return value in function returning > + value by reference, also make the split part return void, otherwise > + we expansion would try to create a non-POD temporary, which is > + invalid. */ > + if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun) > + && DECL_RESULT (current_function_decl) > + && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) > + current->split_part_set_retval = false; > + else > + current->split_part_set_retval = true; > + } > else if (is_gimple_min_invariant (retval)) > current->split_part_set_retval = false; > /* Special case is value returned by reference we record as if it was non-ssa > --- gcc/testsuite/g++.dg/ipa/pr69241-4.C.jj 2016-02-11 13:00:04.160075417 +0100 > +++ gcc/testsuite/g++.dg/ipa/pr69241-4.C 2016-02-11 13:00:04.160075417 +0100 > @@ -0,0 +1,55 @@ > +// PR ipa/69241 > +// { dg-do compile { target c++11 } } > +// { dg-options "-O2 -Wno-return-type" } > + > +template <typename> class A; > +struct B { > + using pointer = int *; > +}; > +template <typename _CharT, typename = A<_CharT>> class basic_string { > + long _M_string_length; > + enum { _S_local_capacity = 15 } _M_local_buf[_S_local_capacity]; > + B::pointer _M_local_data; > + > +public: > + ~basic_string(); > +}; > +template <typename _CharT, typename _Traits, typename _Alloc> > +int operator<<(_Traits, basic_string<_CharT, _Alloc>); > +class C { > + basic_string<A<char>> _M_string; > +}; > +class D { > + C _M_stringbuf; > +}; > +class F { > + int stream; > + D stream_; > +}; > +class G { > +public: > + void operator&(int); > +}; > +class H { > +public: > + H(unsigned); > + H(H &&); > + bool m_fn1(); > +}; > +class I { > + void m_fn2(const int &&); > + static H m_fn3(const int &); > +}; > +template <typename Functor> void Bind(Functor); > +class J { > +public: > + static basic_string<char> m_fn4(); > +}; > +int a; > +void I::m_fn2(const int &&) { Bind(m_fn3); } > +H I::m_fn3(const int &) { > + !false ? (void)0 : G() & F() << J::m_fn4(); > + H b(a); > + if (b.m_fn1()) > + F(); > +} > > Jakub > >
--- gcc/ipa-split.c.jj 2016-02-11 12:46:15.975777652 +0100 +++ gcc/ipa-split.c 2016-02-11 13:06:57.715241871 +0100 @@ -629,7 +629,18 @@ consider_split (struct split_point *curr 4) For non-SSA we need to look where the var is computed. */ retval = find_retval (return_bb); if (!retval) - current->split_part_set_retval = true; + { + /* If there is a return_bb with no return value in function returning + value by reference, also make the split part return void, otherwise + we expansion would try to create a non-POD temporary, which is + invalid. */ + if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun) + && DECL_RESULT (current_function_decl) + && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) + current->split_part_set_retval = false; + else + current->split_part_set_retval = true; + } else if (is_gimple_min_invariant (retval)) current->split_part_set_retval = false; /* Special case is value returned by reference we record as if it was non-ssa --- gcc/testsuite/g++.dg/ipa/pr69241-4.C.jj 2016-02-11 13:00:04.160075417 +0100 +++ gcc/testsuite/g++.dg/ipa/pr69241-4.C 2016-02-11 13:00:04.160075417 +0100 @@ -0,0 +1,55 @@ +// PR ipa/69241 +// { dg-do compile { target c++11 } } +// { dg-options "-O2 -Wno-return-type" } + +template <typename> class A; +struct B { + using pointer = int *; +}; +template <typename _CharT, typename = A<_CharT>> class basic_string { + long _M_string_length; + enum { _S_local_capacity = 15 } _M_local_buf[_S_local_capacity]; + B::pointer _M_local_data; + +public: + ~basic_string(); +}; +template <typename _CharT, typename _Traits, typename _Alloc> +int operator<<(_Traits, basic_string<_CharT, _Alloc>); +class C { + basic_string<A<char>> _M_string; +}; +class D { + C _M_stringbuf; +}; +class F { + int stream; + D stream_; +}; +class G { +public: + void operator&(int); +}; +class H { +public: + H(unsigned); + H(H &&); + bool m_fn1(); +}; +class I { + void m_fn2(const int &&); + static H m_fn3(const int &); +}; +template <typename Functor> void Bind(Functor); +class J { +public: + static basic_string<char> m_fn4(); +}; +int a; +void I::m_fn2(const int &&) { Bind(m_fn3); } +H I::m_fn3(const int &) { + !false ? (void)0 : G() & F() << J::m_fn4(); + H b(a); + if (b.m_fn1()) + F(); +}
On Thu, Feb 11, 2016 at 10:22:24AM +0100, Richard Biener wrote: > The other option is to simply not split the function in this case. Here is a better fix (but it needs the other patch I've sent, so that what is return_bb stays the same). This patch arranges for the case where there is return_bb, but does not return a value, in function that has return type TREE_ADDRESSABLE, to just use void return type from the split part (because we would never set lhs of the call to *.part.* in that case anyway). Bootstrapped/regtested on x86_64-linux and i686-linux on top of the PR68672 patch, ok for trunk? 2016-02-10 Jakub Jelinek <jakub@redhat.com> PR ipa/69241 * ipa-split.c (split_function): If split part returns TREE_ADDRESSABLE type by reference, force lhs on the call. * g++.dg/ipa/pr69241-4.C: New test. Jakub