Bug 39086 - [4.4 Regression] ICE in decl_ultimate_origin, at dwarf2out.c:5770 when compiling with -fno-tree-sra
Summary: [4.4 Regression] ICE in decl_ultimate_origin, at dwarf2out.c:5770 when compil...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.4.0
: P2 normal
Target Milestone: 4.4.0
Assignee: Jason Merrill
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2009-02-03 15:07 UTC by Martin Jambor
Modified: 2009-03-11 05:02 UTC (History)
6 users (show)

See Also:
Host:
Target: i686-pc-linux-gnu
Build:
Known to work: 4.3.3
Known to fail: 4.4.0
Last reconfirmed: 2009-03-07 16:48:47


Attachments
Preprocessed source (5.10 KB, application/octet-stream)
2009-02-03 15:09 UTC, Martin Jambor
Details
Preprocessed source (92.38 KB, application/octet-stream)
2009-02-03 16:56 UTC, Martin Jambor
Details
reduced testcase (1.14 KB, text/plain)
2009-02-05 22:44 UTC, Richard Biener
Details
pr39086.C (393 bytes, text/plain)
2009-02-06 09:35 UTC, Jakub Jelinek
Details
pr39086.C (374 bytes, text/plain)
2009-02-06 16:23 UTC, Jakub Jelinek
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Jambor 2009-02-03 15:07:28 UTC
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.
Comment 1 Martin Jambor 2009-02-03 15:09:06 UTC
Created attachment 17232 [details]
Preprocessed source

Enough to compile with -O2 -g -fno-tree-sra explicit_instantiation.ii
Comment 2 Richard Biener 2009-02-03 15:30:10 UTC
Not too useful, that preprocessed source includes PCHs.
Comment 3 Martin Jambor 2009-02-03 16:56:54 UTC
Created attachment 17236 [details]
Preprocessed source

OK, this one is hopefully without any precompiled headers.
Comment 4 Andrew Pinski 2009-02-04 21:14:46 UTC
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.
Comment 5 H.J. Lu 2009-02-04 23:54:12 UTC
It is a regression introduced between revision 139502 and revision 139996.
I am doing a binary search on it.
Comment 6 H.J. Lu 2009-02-05 01:27:47 UTC
It is caused by revision 139755:

http://gcc.gnu.org/ml/gcc-cvs/2008-08/msg01320.html
Comment 7 Richard Biener 2009-02-05 22:06:18 UTC
Reducing.
Comment 8 Richard Biener 2009-02-05 22:44:58 UTC
Created attachment 17254 [details]
reduced testcase

ICEs with -O2 -fno-tree-sra -g [-m32]
Comment 9 Richard Biener 2009-02-05 22:48:14 UTC
4.3 rejects the reduced testcase, the original works though.

Comment 10 Jakub Jelinek 2009-02-05 23:39:27 UTC
Just s/class ios_base/struct ios_base/ if you don't want 4.3 to reject it.
Comment 11 Jakub Jelinek 2009-02-06 09:35:05 UTC
Created attachment 17261 [details]
pr39086.C

Slightly more reduced testcase.
Comment 12 Jakub Jelinek 2009-02-06 10:54:40 UTC
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.

Comment 13 Jakub Jelinek 2009-02-06 16:23:47 UTC
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.).
Comment 14 Jakub Jelinek 2009-02-06 16:37:44 UTC
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.
Comment 15 Jakub Jelinek 2009-02-09 12:54:06 UTC
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.
Comment 16 Jason Merrill 2009-03-07 20:16:16 UTC
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.
Comment 17 Jason Merrill 2009-03-11 05:01:50 UTC
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

Comment 18 Jason Merrill 2009-03-11 05:02:17 UTC
Fixed.