Created attachment 34087 [details] Test case (unpack, run "make") Using GCC 5.0.0 20141121, the attached program fails with the following ICE. To reproduce: Unpack and hit "make". It will compile one.ii and two.ii and gcc-ar them to libonetwo.ii; it compiles three.ii - and then LTOs them together. (Requires an LD with plugin capabilities; I've put the git version of binutils into the path.) The failure is: 0xa36e4f crash_signal ../../gcc/toplev.c:359 0xc97211 tree_check(tree_node*, char const*, int, char const*, tree_code) ../../gcc/tree.h:2758 0xc97211 get_binfo_at_offset(tree_node*, long, tree_node*) ../../gcc/tree.c:11914 0x884cf4 possible_polymorphic_call_targets(tree_node*, long, ipa_polymorphic_call_context, bool*, void**, bool) ../../gcc/ipa-devirt.c:2404 0x7ef9d7 possible_polymorphic_call_targets(tree_node*, gimple_statement_base*, bool*, void**) ../../gcc/ipa-utils.h:126 0x7edcd0 gimple_fold_call ../../gcc/gimple-fold.c:2667 0x7edcd0 fold_stmt_1 ../../gcc/gimple-fold.c:3246 0xb55323 execute ../../gcc/tree-ssa-forwprop.c:2228
This is a case of -O0 vs -O2 (during final link): Further reduced: markus@x4 testcase % cat one.ii class Validator { public: virtual ~Validator (); }; class FooWriter { Validator *validator; ~FooWriter (); }; FooWriter::~FooWriter () { delete validator; } markus@x4 testcase % g++ -flto -std=c++11 -c one.ii markus@x4 testcase % g++ -r -nostdlib -O2 -flto one.o one.ii: In member function ‘__base_dtor ’: one.ii:11:1: internal compiler error: Segmentation fault FooWriter::~FooWriter () { delete validator; } ^ 0x9dc45f crash_signal ../../gcc/gcc/toplev.c:359 0xc3f211 tree_check ../../gcc/gcc/tree.h:2758 0xc3f211 get_binfo_at_offset(tree_node*, long, tree_node*) ../../gcc/gcc/tree.c:11914 0x82855b possible_polymorphic_call_targets(tree_node*, long, ipa_polymorphic_call_context, bool*, void**, bool) ../../gcc/gcc/ipa-devirt.c:2404 0x792a2f possible_polymorphic_call_targets(tree_node*, gimple_statement_base*, bool*, void**) ../../gcc/gcc/ipa-utils.h:126 0x790c4a gimple_fold_call ../../gcc/gcc/gimple-fold.c:2667 0x790c4a fold_stmt_1 ../../gcc/gcc/gimple-fold.c:3246 0xafb1a3 execute ../../gcc/gcc/tree-ssa-forwprop.c:2228 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. lto-wrapper: fatal error: /var/tmp/gcc_test/usr/local/bin/g++ returned 1 exit status compilation terminated. /usr/bin/ld: fatal error: lto-wrapper failed collect2: error: ld returned 1 exit status
Mine.
OK, the problem is that the unit is compiled without -O2 and -fdevirtualize is not properly marked as Optimization (have separate patch for this). However it seems that for units that are not optimized with -fdevirtualize we can just drop OBJ_TYPE_REF and save some of IL memory? Jason, does this have chance to interfere with devirtualization required by C++ language that happens at -fno-devirtualize too? Honza Index: cp/class.c =================================================================== --- cp/class.c (revision 218249) +++ cp/class.c (working copy) @@ -736,7 +736,8 @@ build_vfn_ref (tree instance_ptr, tree i cp_build_addr_expr (aref, tf_warning_or_error)); /* Remember this as a method reference, for later devirtualization. */ - aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx); + if (flag_devirtualize) + aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx); return aref; } Index: testsuite/g++.dg/lto/pr64043_0.C =================================================================== --- testsuite/g++.dg/lto/pr64043_0.C (revision 0) +++ testsuite/g++.dg/lto/pr64043_0.C (revision 0) @@ -0,0 +1,14 @@ +// { dg-lto-do link } +// { dg-lto-options { { -flto -std=c++11 } } } +// { dg-extra-ld-options "-r -nostdlib -O2" } +class Validator +{ +public: + virtual ~Validator (); +}; +class FooWriter +{ + Validator *validator; + ~FooWriter (); +}; +FooWriter::~FooWriter () { delete validator; }
Actually my tree has flag_devirtualize marked as Optimization, as a separate problem I need to figure out how it happens to be true.
(In reply to Jan Hubicka from comment #3) > Jason, does this have chance to interfere with devirtualization required by > C++ language that happens at -fno-devirtualize too? No, non-virtual calls to virtual functions never make it to build_vfn_ref.
*** Bug 64285 has been marked as a duplicate of this bug. ***
Now fails with the following backtrace. The location of the failure might have changed due to the patch at https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01076.html ; in any case, currently the failure is: foo.ii: In member function ‘__base_dtor ’: foo.ii:11:1: internal compiler error: Segmentation fault FooWriter::~FooWriter () { delete validator; } ^ 0xa1f99f crash_signal ../../gcc/toplev.c:358 0x873daf tree_check(tree_node*, char const*, int, char const*, tree_code) ../../gcc/tree.h:2778 0x873daf ipa_polymorphic_call_context::get_dynamic_type(tree_node*, tree_node*, tree_node*, gimple_statement_base*) 0xb9787e eliminate_dom_walker::before_dom_children(basic_block_def*) ../../gcc/tree-ssa-pre.c:4334
The following patch should help. Still need to work out why flag_devirtualize is set at final link - it should not Index: tree.c =================================================================== --- tree.c (revision 218658) +++ tree.c (working copy) @@ -11870,6 +11870,11 @@ if (TREE_CODE (target) == FUNCTION_TYPE) return false; gcc_checking_assert (TREE_CODE (target) == METHOD_TYPE); + /* If we do not have BINFO associated, it means that type was built + without devirtualization enabled. Do not consider this a virtual + call. */ + if (!TYPE_BINFO (obj_type_ref_class (target))) + return false; return true; }
Author: hubicka Date: Mon Dec 15 03:41:41 2014 New Revision: 218727 URL: https://gcc.gnu.org/viewcvs?rev=218727&root=gcc&view=rev Log: PR lto/64043 * tree.c (virtual_method_call_p): Return false when OTR type has no BINFO. * g++.dg/lto/pr64043_0.C: New testcase. Added: trunk/gcc/testsuite/g++.dg/lto/pr64043_0.C Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree.c
Author: hubicka Date: Mon Dec 15 22:35:20 2014 New Revision: 218767 URL: https://gcc.gnu.org/viewcvs?rev=218767&root=gcc&view=rev Log: PR lto/64043 * gcc.dg/lto/20110201-1_0.c: New testcase. * tree-streamer.c (preload_common_nodes): Skip preloading of main_identifier_node, pid_type and optimization/option nodes. Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/lto/20110201-1_0.c trunk/gcc/tree-streamer.c
This breaks ada: $ gcc/gnatmake --GCC=gcc/xgcc --GNATBIND=gcc/gnatbind --GNATLINK=gcc/gnatlink -cargs -Bgcc/ -largs '--GCC=gcc/xgcc -Bgcc' -margs --RTS=ia64-suse-linux/./libada -f ../gcc/testsuite/gnat.dg/lto8.adb -gnatws -flto -lm -o ./lto8.exe gcc/xgcc -c -I../gcc/testsuite/gnat.dg/ -Bgcc/ --RTS=ia64-suse-linux/./libada -gnatws -flto -lm -I- ../gcc/testsuite/gnat.dg/lto8.adb gcc/xgcc -c -I../gcc/testsuite/gnat.dg/ -Bgcc/ --RTS=ia64-suse-linux/./libada -gnatws -flto -lm -I- ../gcc/testsuite/gnat.dg/lto8_pkg.adb gcc/gnatbind --RTS=ia64-suse-linux/./libada -x lto8.ali gcc/gnatlink lto8.ali --GCC=gcc/xgcc -Bgcc -flto -o ./lto8.exe ../gcc/testsuite/gnat.dg/lto8_pkg.ads: In function ‘lto8_pkg___elabs’: ../gcc/testsuite/gnat.dg/lto8_pkg.ads:4:1: internal compiler error: in expand_gimple_stmt_1, at cfgexpand.c:3420 package Lto8_Pkg is ^ 0x400000000026d36f expand_gimple_stmt_1 ../../gcc/cfgexpand.c:3420 0x400000000026e52f expand_gimple_stmt ../../gcc/cfgexpand.c:3447 0x400000000027014f expand_gimple_basic_block ../../gcc/cfgexpand.c:5280 0x400000000027453f execute ../../gcc/cfgexpand.c:5889 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. lto-wrapper: fatal error: /usr/local/gcc/test/Build/gcc/xgcc returned 1 exit status
> This breaks ada: ... It is now pr64340.
I also see performance degradation for several spec2006 tests after this commit (mostly on FP tests). Eg. on Haswell 433.milc shows ~-7-8% if compiled with "-O3 -flto -funroll-loops -march=core-avx2" Not investigated this so far though
Hi, do you use same flags at compile time and link time? I did not see anything unusual at our testers, but perhaps some of the optimization flags are streamed wrong? Honza
Just checked: everywhere "-Ofast -flto -funroll-loops -static -m64 -march=core-avx2" used (not -O3 as I mentioned before)
Hi, Honza! I still see that performance degradations for spec2006 tests. Could you please check those on your side?
Unforutnately it is a bit difficult without Haswell machine. Would be possible to profile it and post the difference in internal loops? Possibly the target option node is not streamed fully and some flags are getting lost, though I do not see how that can happen...
Igor, I believe the perofmrance issue is fixed and the Ada issue is separate PR. I think we can close this PR. If performance issue remain, please just open PR for that. The original problem is fixed now.