When compiling test 27_io/basic_istream/requirements/explicit_instantiation.cc from the libstc++ testsuite and adding the -fno-tree-sra flag, I get the following error: ---------------------------------------------------------------------- user@host:~/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/testsuite$ $HOME/gcc/svn/obj/./gcc/g++ -shared-libgcc -B$HOME/gcc/svn/obj/./gcc -nostdinc++ -L$HOME/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/src -L$HOME/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/src/.libs -B$HOME/gcc/inst/svn//i686-pc-linux-gnu/bin/ -B$HOME/gcc/inst/svn//i686-pc-linux-gnu/lib/ -isystem $HOME/gcc/inst/svn//i686-pc-linux-gnu/include -isystem $HOME/gcc/inst/svn//i686-pc-linux-gnu/sys-include -g -O2 -D_GLIBCXX_ASSERT -fmessage-length=0 -ffunction-sections -fdata-sections -g -O2 -D_GNU_SOURCE -g -O2 -D_GNU_SOURCE -DLOCALEDIR="." -nostdinc++ -I$HOME/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/include/i686-pc-linux-gnu -I$HOME/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/include -I$HOME/gcc/svn/libstdc++-v3/libsupc++ -I$HOME/gcc/svn/libstdc++-v3/include/backward -I$HOME/gcc/svn/libstdc++-v3/testsuite/util $HOME/gcc/svn/libstdc++-v3/testsuite/27_io/basic_istream/requirements/explicit_instantiation.cc -include bits/stdc++.h -S -o explicit_instantiation.s -fno-tree-sra In file included from $HOME/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/include/istream:833, from $HOME/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/include/sstream:44, from $HOME/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/include/complex:52, from $HOME/gcc/svn/libstdc++-v3/include/precompiled/stdc++.h:69: $HOME/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/include/bits/istream.tcc: In member function 'typename std::basic_istream<_CharT, _Traits>::int_type std::basic_istream<_CharT, _Traits>::get() [with _CharT = __gnu_cxx::character<unsigned char, __gnu_test::pod_int, __gnu_test::pod_state>, _Traits = std::char_traits<__gnu_cxx::character<unsigned char, __gnu_test::pod_int, __gnu_test::pod_state> >]': $HOME/gcc/svn/obj/i686-pc-linux-gnu/libstdc++-v3/include/bits/istream.tcc:222: internal compiler error: in decl_ultimate_origin, at dwarf2out.c:5770 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. ---------------------------------------------------------------------- This is with trunk revision 143890, compiled on i686-pc-linux without bootstrap. I will attach preprocessed source shortly.
Created attachment 17232 [details] Preprocessed source Enough to compile with -O2 -g -fno-tree-sra explicit_instantiation.ii
Not too useful, that preprocessed source includes PCHs.
Created attachment 17236 [details] Preprocessed source OK, this one is hopefully without any precompiled headers.
It fails with gcc version 4.4.0 20090116 (experimental) [trunk revision 143440] (GCC) But I don't have anything older to try it with on that machine. It did work with gcc version 4.4.0 20081229 (experimental) [trunk revision 142951] (GCC) on i386-darwin8.11. I don't have time right now to figure out if this is really a regression or not or a reduced testcase but I am going to mark it as a regression so at least someone will look at it. I really think it is a regression.
It is a regression introduced between revision 139502 and revision 139996. I am doing a binary search on it.
It is caused by revision 139755: http://gcc.gnu.org/ml/gcc-cvs/2008-08/msg01320.html
Reducing.
Created attachment 17254 [details] reduced testcase ICEs with -O2 -fno-tree-sra -g [-m32]
4.3 rejects the reduced testcase, the original works though.
Just s/class ios_base/struct ios_base/ if you don't want 4.3 to reject it.
Created attachment 17261 [details] pr39086.C Slightly more reduced testcase.
Seems that 2008-08-29 patch effect on this testcase is that __builtin_expect is removed later and it apparently isn't considered as zero cost. This is strange, as gimple_reg = gimple_reg2 is considered to have 0 cost. I think __builtin_expect shouldn't count the cost of the second argument and for the first argument if lhs of the call is_gimple_reg and so is the first call argument, it should also return 0 cost.
Created attachment 17262 [details] pr39086.C Even more reduced testcase on which g++ -O2 -W -Wall is quiet (no missing returns in functions returning non-void etc.).
The problem is with f4 RESULT_DECL. First during save_inline_function_body remap_decl creates a copy of that RESULT_DECL and sets copy's DECL_ABSTRACT_ORIGIN to the original f4's RESULT_DECL. Then during optimization of the original f4 tree_nrv sets the original f4 RESULT_DECL's DECL_ABSTRACT_ORIGIN to found's DECL_ABSTRACT_ORIGIN (where found is a VAR_DECL originally from f1). But at this point decl_ultimate_origin will already ICE on the inlined f4's RESULT_DECL, as its DECL_ABSTRACT_ORIGIN has another DECL_ABSTRACT_ORIGIN, so it is not ultimate anymore. I have no idea how to prevent this though.
And, even if decl_ultimate_origin checking is weakened and it actually looks for ultimate origin for RESULT_DECLs, I'm not sure the generated debug info is correct. The problem is that the tree NRV optimization is an optimization in the current function only, it shouldn't affect inlined copies of that function. When foo is inlined into bar, in bar there is some VAR_DECL with abstract origin in foo's RESULT_DECL. In foo, if tree NRV kicks in, RESULT_DECL has abstract origin some VAR_DECL. But that was a result of a local optimization of foo, it doesn't mean that the VAR_DECL in bar with foo's RESULT_DECL as abstract origin should have that other var in foo as origin. Perhaps we'd need to emit a virtual foo's info and then emit real out-of-line foo as "inlined instance" of that virtual foo or something to get proper debug info.
So here's what happens: 1) The front end chooses 'x' as the NRV for f4 and rewrites the assignments. 2) inlining creates a temporary variable for the return value of f1. So we have <bb 3>: D.1204 = ax; <retval> = D.1204; goto <bb 5>; <bb 4>: <retval> = OBJ_TYPE_REF(*this->_vptr.C;this->0) (this); 3) tree-nrv looks at this, sees <retval> = D.1204, doesn't see the other assignment to retval because it's a GIMPLE_CALL rather than a GIMPLE_ASSIGN, and decides to make D.1204 the NRV. 4) tree-nrv copies the debugging information for D.1204 over the debugging information for the f4 return value, which already had the info for 'x'. 5) The f4 retval now has DECL_ABSTRACT_ORIGIN referring to f1, which causes chaos. It seems that there are several bugs here: * tree-nrv shouldn't do NRV after the front end already did, as it might miss modifications that aren't of the form it expects. Specifically, it doesn't seem to check whether anything takes the address of the RESULT_DECL. * tree-nrv needs to notice GIMPLE_CALL modifications. * tree-nrv shouldn't clobber the debug information on the RESULT_DECL in favor of another artificial variable. * tree-nrv shouldn't copy DECL_ABSTRACT_ORIGIN that refers to another function. I'm working on a patch for all these issues.
Subject: Bug 39086 Author: jason Date: Wed Mar 11 05:01:30 2009 New Revision: 144772 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=144772 Log: PR debug/39086 * tree-nrv.c (tree_nrv): Don't do this optimization if the front end already did. Notice GIMPLE_CALL modifications of the result. Don't copy debug information from an ignored decl or a decl from another function. Added: trunk/gcc/testsuite/g++.dg/opt/nrv15.C Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-nrv.c
Fixed.