Bug 93318 - [10 regression] Firefox LTO+FDO ICEs in speculative_call_info
Summary: [10 regression] Firefox LTO+FDO ICEs in speculative_call_info
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: ipa (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: 10.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, lto
Depends on:
Blocks: mozillametabug
  Show dependency treegraph
 
Reported: 2020-01-18 16:12 UTC by Jan Hubicka
Modified: 2022-05-13 10:07 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-01-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Hubicka 2020-01-18 16:12:02 UTC
Firefox build now crashes with:
36:24.63 0x7ffff756505f ???
36:24.63        /build/glibc-77giwP/glibc-2.24/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
36:24.67 0x6d9524 cgraph_edge::speculative_call_info(cgraph_edge*&, cgraph_edge*&, ipa_ref*&)
36:24.67        ../../gcc/cgraph.c:1137
36:24.79 0xb00685 copy_bb
36:24.80        ../../gcc/tree-inline.c:2220
36:24.80 0xb00d3c copy_cfg_body
36:24.80        ../../gcc/tree-inline.c:3012
36:24.80 0xb00d3c copy_body
36:24.80        ../../gcc/tree-inline.c:3260
36:24.80 0xb03cb8 expand_call_inline
36:24.80        ../../gcc/tree-inline.c:5051
36:24.80 0xb05239 gimple_expand_calls_inline
36:24.80        ../../gcc/tree-inline.c:5241
36:24.80 0xb05239 optimize_inline_calls(tree_node*)
36:24.80        ../../gcc/tree-inline.c:5383
36:24.83 0x12d7f9b inline_transform(cgraph_node*) 
36:24.83        ../../gcc/ipa-inline-transform.c:722
36:24.88 0x9dc425 execute_one_ipa_transform_pass  
36:24.88        ../../gcc/passes.c:2231
36:24.88 0x9dc425 execute_all_ipa_transforms(bool)
36:24.88        ../../gcc/passes.c:2270
36:24.90 0x6e0b95 cgraph_node::expand()
36:24.91        ../../gcc/cgraphunit.c:2276
36:24.91 0x6e1bc7 expand_all_functions
36:24.91        ../../gcc/cgraphunit.c:2439
36:24.91 0x6e1bc7 symbol_table::compile()
36:24.91        ../../gcc/cgraphunit.c:2804
36:24.94 0x65b7a1 lto_main()
36:24.94        ../../gcc/lto/lto.c:658
Comment 1 Jan Hubicka 2020-01-18 16:20:50 UTC
So it seems the problem is the following:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000a1ff0e in cgraph_edge::speculative_call_info (this=0x7ffff6e26bc8, direct=@0x7fffffffd700: 0x90c070 <_start>, indirect=@0x7fffffffd6f8: 0x7fffffffd740,
    reference=@0x7fffffffd6f0: 0x3c94d50) at ../../gcc/cgraph.c:1137
1137             e2->call_stmt != e->call_stmt || e2->lto_stmt_uid != e->lto_stmt_uid;
(gdb) p e->call-stmt
No symbol "stmt" in current context.
(gdb) p e
$1 = (cgraph_edge *) 0x7ffff6e26bc8
(gdb) p e2
$2 = (cgraph_edge *) 0x0
(gdb) p e->caller->debug ()
_ZN2js8frontend12FunctionTree16visitRecursivelyEP9JSContextPNS0_10ParserBaseEPFbS5_PS1_E/35640856 (visitRecursively) @0x7ffff5ea7ca8
  Type: function definition analyzed
  Visibility: public visibility_specified visibility:hidden
  References: _ZZN2js8frontend10ParserBase24publishDeferredFunctionsEPNS0_12FunctionTreeEENUlPS1_S3_E_4_FUNES4_S3_.lto_priv.0/33954802 (addr) (speculative)
  Referring:
  Function visitRecursively/35640856 is inline copy in publishDeferredItems/33218091
  Clone of _ZN2js8frontend12FunctionTree16visitRecursivelyEP9JSContextPNS0_10ParserBaseEPFbS5_PS1_E/33948009
  Availability: local
  Unit id: 2276
  Function flags: count:2174 (guessed) first_run:4520 body local
  Called by: _ZN2js8frontend10ParserBase20publishDeferredItemsEPNS0_12FunctionTreeE/33218091 (inlined) (2174 (guessed),1.00 per call)
  Calls: _ZZN2js8frontend10ParserBase24publishDeferredFunctionsEPNS0_12FunctionTreeEENUlPS1_S3_E_4_FUNES4_S3_.lto_priv.0/35640861 (speculative) (inlined) (indirect_inlining) (1558 (guessed),0.72 per call) __builtin_expect/10953 (2078 (guessed),0.96 per call) __builtin_expect/10953 (2078 (guessed),0.96 per call) _ZN2js28RunningWithTrustedPrincipalsEP9JSContext/32911428 (0 (precise),0.00 per call) __builtin_expect/10953 (0 (precise),0.00 per call) _ZN2js18ReportOverRecursedEP9JSContext/33263266 (0 (precise),0.00 per call) _ZN2js8frontend12FunctionTree16visitRecursivelyEP9JSContextPNS0_10ParserBaseEPFbS5_PS1_E/33948009 (0 (precise),0.00 per call) _ZZN2js8frontend10ParserBase24publishDeferredFunctionsEPNS0_12FunctionTreeEENUlPS1_S3_E_4_FUNES4_S3_.lto_priv.0/35640859 (speculative) (inlined) (543 (guessed),0.25 per call)


We have two speculative calls direct edges:
1)_ZZN2js8frontend10ParserBase24publishDeferredFunctionsEPNS0_12FunctionTreeEENUlPS1_S3_E_4_FUNES4_S3_.lto_priv.0/35640861 (speculative) (inlined)
2) _ZZN2js8frontend10ParserBase24publishDeferredFunctionsEPNS0_12FunctionTreeEENUlPS1_S3_E_4_FUNES4_S3_.lto_priv.0/35640859 (speculative) (inlined) (543 (guessed),0.25 per call)

and one speculative reference, but no indirect call.
Comment 2 Jan Hubicka 2020-01-18 19:12:59 UTC
The problem happens at WPA. We end up producing unmatched indirect call.
We produce speculative call and later try to resolve it to direct call:
(gdb) up
#1  0x0000000000a1fca9 in cgraph_edge::remove (edge=0x7fff8a778a28) at ../../gcc/cgraph.c:1027
1027      edge->remove_caller ();
(gdb) 
#2  0x0000000000a20368 in cgraph_edge::resolve_speculation (edge=0x7fff8a7764e0, callee_decl=0x7fff9803ed00) at ../../gcc/cgraph.c:1246
1246        remove (e2);
(gdb) 
#3  0x0000000000a20403 in cgraph_edge::make_direct (edge=0x7fff8a778a28, callee=0x7fff79251b40) at ../../gcc/cgraph.c:1266
1266          edge = resolve_speculation (edge, callee->decl);
(gdb) 
#4  0x0000000000d394b8 in ipa_make_edge_direct_to_target (ie=0x7fff8a778a28, target=0x7fff9803ed00, speculative=false) at ../../gcc/ipa-prop.c:3305
3305          ie = cgraph_edge::make_direct (ie, callee);
(gdb) 
#5  0x0000000000d39f09 in try_make_edge_direct_simple_call (ie=0x7fff8a778a28, jfunc=0x7fff601b4870, target_type=0x7fff9800a3f0, new_root=0x7fff7a06c000, 
    new_root_info=0x7fff608a0a80) at ../../gcc/ipa-prop.c:3590
3590      cs = ipa_make_edge_direct_to_target (ie, target);
(gdb) 
#6  0x0000000000d3a82f in update_indirect_edges_after_inlining (cs=0x7fff792d54e0, node=0x7fff858fe000, new_edges=0x7fffffffdd98) at ../../gcc/ipa-prop.c:3812
3812              new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
(gdb) 

after this we already have one speculative edge but no indirect edge:

_ZN2js8frontend12FunctionTree16visitRecursivelyEP9JSContextPNS0_10ParserBaseEPFbS5_PS1_E/35641710 (visitRecursively) @0x7fff858fe000
  Type: function definition analyzed
  Visibility:
  next sharing asm name: 35638756
  References: _ZZN2js8frontend10ParserBase24publishDeferredFunctionsEPNS0_12FunctionTreeEENUlPS1_S3_E_4_FUNES4_S3_/33954806 (addr) (speculative)
  Referring: 
  Read from file: ../../../js/src/build/libjs_static.a
  Function visitRecursively/35641710 is inline copy in publishDeferredItems/33218097
  Clone of _ZN2js8frontend12FunctionTree16visitRecursivelyEP9JSContextPNS0_10ParserBaseEPFbS5_PS1_E/33948013
  Availability: local
  Unit id: 2275
  Function flags: count:24992 (guessed) first_run:4521 local hot
  Called by: _ZN2js8frontend10ParserBase18publishLazyScriptsEPNS0_12FunctionTreeE/33954804 (inlined) (24992 (guessed),1.00 per call) 
  Calls: __builtin_expect/10953 (24992 (guessed),1.00 per call) __builtin_expect/10953 (24992 (guessed),1.00 per call) _ZN2js28RunningWithTrustedPrincipalsEP9JSContext/32911433 (0 (precise),0.00 per call) __builtin_expect/10953 (0 (precise),0.00 per call) _ZN2js18ReportOverRecursedEP9JSContext/33263272 (0 (precise),0.00 per call) _ZN2js8frontend12FunctionTree16visitRecursivelyEP9JSContextPNS0_10ParserBaseEPFbS5_PS1_E/33948013 (0 (precise),0.00 per call) _ZZN2js8frontend10ParserBase18publishLazyScriptsEPNS0_12FunctionTreeEENUlPS1_S3_E_4_FUNES4_S3_/35641711 (inlined) (18743 (guessed),0.75 per call) _ZZN2js8frontend10ParserBase24publishDeferredFunctionsEPNS0_12FunctionTreeEENUlPS1_S3_E_4_FUNES4_S3_/35641713 (speculative) (inlined) (6249 (guessed),0.25 per call) 


It seems that resolve_speculation is broken.  It definitely should not leave the call in inconsistent shape. Also the new code documents that one needs to iterate on speculations which is not done by cgraph_edge::make_direct
Comment 3 GCC Commits 2020-01-19 12:51:27 UTC
The master branch has been updated by Jan Hubicka <hubicka@gcc.gnu.org>:

https://gcc.gnu.org/g:118aa5e31ce479bb81a003199b4c6ca0d997c9a2

commit r10-6074-g118aa5e31ce479bb81a003199b4c6ca0d997c9a2
Author: Jan Hubicka <jh@suse.cz>
Date:   Sun Jan 19 13:49:38 2020 +0100

    Fix ICE in speculative_call_info
    
    this fixes two issues with the new multi-target speculation code which reproduce
    on Firefox.  I can now build firefox with FDO locally but on Mozilla build bots
    it still fails with ICE in speculative_call_info.
    
    One problem is that speuclative code compares call_stmt and lto_stmt_uid in
    a way that may get unwanted effect when these gets out of sync.  It does not
    make sense to have both non-zero so I added code clearing it and sanity check
    that it is kept this way.
    
    Other problem is cgraph_edge::make_direct not working well with multiple
    targets.  In this case it removed one speuclative target and the indirect call
    leaving other targets in the tree.
    
    This is fixed by iterating across all targets and removing all except the good
    one (if it exists).
    
    	PR lto/93318
    	* cgraph.c (cgraph_edge::resolve_speculation): Fix foramting.
    	(cgraph_edge::make_direct): Remove all indirect targets.
    	(cgraph_edge::redirect_call_stmt_to_callee): Use make_direct..
    	(cgraph_node::verify_node): Verify that only one call_stmt or
    	lto_stmt_uid is set.
    	* cgraphclones.c (cgraph_edge::clone): Set only one call_stmt or
    	lto_stmt_uid.
    	* lto-cgraph.c (lto_output_edge): Simplify streaming of stmt.
    	(lto_output_ref): Simplify streaming of stmt.
    	* lto-streamer-in.c (fixup_call_stmt_edges_1): Clear lto_stmt_uid.
Comment 4 Jan Hubicka 2020-01-19 23:09:46 UTC
Ok,
I managed to reproduce the crash locally (it was not that easy)
At the point of failure the node passes verification and I suppose
problem is that the call stmt hash contains indirect call while it is
supposed to contain direct call.

Edge removal code probably replaces direct edge by indreict one since it
does not know about additional speculations.  I will continue tomorrow.

Honza
Comment 5 GCC Commits 2020-01-21 15:34:45 UTC
The master branch has been updated by Jan Hubicka <hubicka@gcc.gnu.org>:

https://gcc.gnu.org/g:28307164dfed294855bf3d55bed357de560f083b

commit r10-6111-g28307164dfed294855bf3d55bed357de560f083b
Author: Jan Hubicka <jh@suse.cz>
Date:   Tue Jan 21 16:33:43 2020 +0100

    Fix updating of call_stmt_site_hash
    
    This patch fixes ICE causes by call stmt site hash going out of sync.  For
    speculative edges it is assumed to contain a direct call so if we are
    removing it hashtable needs to be updated.  I realize that the code is ugly
    but I will leave cleanup for next stage1.
    
    Bootstrapped/regtested x86_64-linux. This patch makes it possible to build
    Firefox again.
    
    	PR lto/93318
    	* cgraph.c (cgraph_edge::resolve_speculation,
    	cgraph_edge::redirect_call_stmt_to_callee): Fix update of
    	call_stmt_site_hash.
Comment 6 Jan Hubicka 2020-01-21 16:08:24 UTC
Firefox builds for me again.
Comment 7 GCC Commits 2020-01-28 19:38:58 UTC
The master branch has been updated by Jan Hubicka <hubicka@gcc.gnu.org>:

https://gcc.gnu.org/g:845bb366adcf702331de3d8022fd0e1c1c918607

commit r10-6299-g845bb366adcf702331de3d8022fd0e1c1c918607
Author: Jan Hubicka <jh@suse.cz>
Date:   Tue Jan 28 20:34:56 2020 +0100

    ipa: fix handling of multiple speculations (PR93318)
    
    This patch started as work to resole Richard's comment on quadratic lookups
    in resolve_speculation. While doing it I however noticed multiple problems
    in the new speuclative call code which made the patch quite big. In
    particular:
     1) Before applying speculation we consider only targets with at lest
        probability 1/2.
        If profile is sane at most two targets can have probability greater or
        equal to 1/2. So the new multi-target speculation code got enabled only
        in very special scenario when there ae precisely two target with precise
        probability 1/2 (which is tested by the single testcase).
    
        As a conseuqence the multiple target logic got minimal test coverage and
        this made us to miss several ICEs.
     2) Profile updating in profile merging, tree-inline and indirect call
        expansion was wrong which led to inconsistent profiles (as already seen
        on the testcase).
     3) Code responsible to turn speculative call to direct call was broken for
        anything with more than one target.
     4) There were multiple cases where call_site_hash went out of sync which
        eventually leads to an ICE..
     5) Some code expects that all speculative call targets forms a sequence in
        the callee linked list but there is no code to maintain that invariant
        nor a verifier.
    Fixing this it became obvious that the current API of speculative_call_info is
    not useful because it really builds on fact tht there are precisely three
    components (direct call, ref and indirect call) in every speculative call
    sequence.  I ended up replacing it with iterator API for direct call
    (first_speculative_call_target, next_speculative_call_target) and accessors for
    the other coponents updating comment in cgraph.h.
    
    Finally I made the work with call site hash more effetive by updating edge
    manipulation to keep them in sequence. So first one can be looked up from the
    hash and then they can be iterated by callee.
    
    There are other things that can be improved (for example the speculation should
    start with most common target first), but I will try to keep that for next
    stage1. This patch is mostly about getting rid of ICE and profile corruption
    which is a regression from GCC 9.
    
    gcc/ChangeLog:
    
    	PR lto/93318
    	* cgraph.c (cgraph_add_edge_to_call_site_hash): Update call site
    	hash only when edge is first within the sequence.
    	(cgraph_edge::set_call_stmt): Update handling of speculative calls.
    	(symbol_table::create_edge): Do not set target_prob.
    	(cgraph_edge::remove_caller): Watch for speculative calls when updating
    	the call site hash.
    	(cgraph_edge::make_speculative): Drop target_prob parameter.
    	(cgraph_edge::speculative_call_info): Remove.
    	(cgraph_edge::first_speculative_call_target): New member function.
    	(update_call_stmt_hash_for_removing_direct_edge): New function.
    	(cgraph_edge::resolve_speculation): Rewrite to new API.
    	(cgraph_edge::speculative_call_for_target): New member function.
    	(cgraph_edge::make_direct): Rewrite to new API; fix handling of
    	multiple speculation targets.
    	(cgraph_edge::redirect_call_stmt_to_callee): Likewise; fix updating
    	of profile.
    	(verify_speculative_call): Verify that targets form an interval.
    	* cgraph.h (cgraph_edge::speculative_call_info): Remove.
    	(cgraph_edge::first_speculative_call_target): New member function.
    	(cgraph_edge::next_speculative_call_target): New member function.
    	(cgraph_edge::speculative_call_target_ref): New member function.
    	(cgraph_edge;:speculative_call_indirect_edge): New member funtion.
    	(cgraph_edge): Remove target_prob.
    	* cgraphclones.c (cgraph_node::set_call_stmt_including_clones):
    	Fix handling of speculative calls.
    	* ipa-devirt.c (ipa_devirt): Fix handling of speculative cals.
    	* ipa-fnsummary.c (analyze_function_body): Likewise.
    	* ipa-inline.c (speculation_useful_p): Use new speculative call API.
    	* ipa-profile.c (dump_histogram): Fix formating.
    	(ipa_profile_generate_summary): Watch for overflows.
    	(ipa_profile): Do not require probablity to be 1/2; update to new API.
    	* ipa-prop.c (ipa_make_edge_direct_to_target): Update to new API.
    	(update_indirect_edges_after_inlining): Update to new API.
    	* ipa-utils.c (ipa_merge_profiles): Rewrite merging of speculative call
    	profiles.
    	* profile-count.h: (profile_probability::adjusted): New.
    	* tree-inline.c (copy_bb): Update to new speculative call API; fix
    	updating of profile.
    	* value-prof.c (gimple_ic_transform): Rename to ...
    	(dump_ic_profile): ... this one; update dumping.
    	(stream_in_histogram_value): Fix formating.
    	(gimple_value_profile_transformations): Update.
    
    gcc/testsuite/ChangeLog:
    
    	* g++.dg/tree-prof/indir-call-prof.C: Update template.
    	* gcc.dg/tree-prof/crossmodule-indircall-1.c: Add more targets.
    	* gcc.dg/tree-prof/crossmodule-indircall-1a.c: Add more targets.
    	* gcc.dg/tree-prof/indir-call-prof.c: Update template.
Comment 8 GCC Commits 2020-01-28 20:31:36 UTC
The master branch has been updated by Jan Hubicka <hubicka@gcc.gnu.org>:

https://gcc.gnu.org/g:40d240315a6e5ff2010769bfa1c19264217b5f1c

commit r10-6301-g40d240315a6e5ff2010769bfa1c19264217b5f1c
Author: Jan Hubicka <jh@suse.cz>
Date:   Tue Jan 28 21:30:14 2020 +0100

    ipa: fix handling of multiple speculations (PR93318)
    
    This patch started as work to resole Richard's comment on quadratic lookups
    in resolve_speculation. While doing it I however noticed multiple problems
    in the new speuclative call code which made the patch quite big. In
    particular:
     1) Before applying speculation we consider only targets with at lest
        probability 1/2.
        If profile is sane at most two targets can have probability greater or
        equal to 1/2. So the new multi-target speculation code got enabled only
        in very special scenario when there ae precisely two target with precise
        probability 1/2 (which is tested by the single testcase).
    
        As a conseuqence the multiple target logic got minimal test coverage and
        this made us to miss several ICEs.
     2) Profile updating in profile merging, tree-inline and indirect call
        expansion was wrong which led to inconsistent profiles (as already seen
        on the testcase).
     3) Code responsible to turn speculative call to direct call was broken for
        anything with more than one target.
     4) There were multiple cases where call_site_hash went out of sync which
        eventually leads to an ICE..
     5) Some code expects that all speculative call targets forms a sequence in
        the callee linked list but there is no code to maintain that invariant
        nor a verifier.
    Fixing this it became obvious that the current API of speculative_call_info is
    not useful because it really builds on fact tht there are precisely three
    components (direct call, ref and indirect call) in every speculative call
    sequence.  I ended up replacing it with iterator API for direct call
    (first_speculative_call_target, next_speculative_call_target) and accessors for
    the other coponents updating comment in cgraph.h.
    
    Finally I made the work with call site hash more effetive by updating edge
    manipulation to keep them in sequence. So first one can be looked up from the
    hash and then they can be iterated by callee.
    
    There are other things that can be improved (for example the speculation should
    start with most common target first), but I will try to keep that for next
    stage1. This patch is mostly about getting rid of ICE and profile corruption
    which is a regression from GCC 9.
    
    Honza
    
    gcc/ChangeLog:
    
    2020-01-28  Jan Hubicka  <hubicka@ucw.cz>
    
    	PR lto/93318
    	* cgraph.c (cgraph_add_edge_to_call_site_hash): Update call site
    	hash only when edge is first within the sequence.
    	(cgraph_edge::set_call_stmt): Update handling of speculative calls.
    	(symbol_table::create_edge): Do not set target_prob.
    	(cgraph_edge::remove_caller): Watch for speculative calls when updating
    	the call site hash.
    	(cgraph_edge::make_speculative): Drop target_prob parameter.
    	(cgraph_edge::speculative_call_info): Remove.
    	(cgraph_edge::first_speculative_call_target): New member function.
    	(update_call_stmt_hash_for_removing_direct_edge): New function.
    	(cgraph_edge::resolve_speculation): Rewrite to new API.
    	(cgraph_edge::speculative_call_for_target): New member function.
    	(cgraph_edge::make_direct): Rewrite to new API; fix handling of
    	multiple speculation targets.
    	(cgraph_edge::redirect_call_stmt_to_callee): Likewise; fix updating
    	of profile.
    	(verify_speculative_call): Verify that targets form an interval.
    	* cgraph.h (cgraph_edge::speculative_call_info): Remove.
    	(cgraph_edge::first_speculative_call_target): New member function.
    	(cgraph_edge::next_speculative_call_target): New member function.
    	(cgraph_edge::speculative_call_target_ref): New member function.
    	(cgraph_edge;:speculative_call_indirect_edge): New member funtion.
    	(cgraph_edge): Remove target_prob.
    	* cgraphclones.c (cgraph_node::set_call_stmt_including_clones):
    	Fix handling of speculative calls.
    	* ipa-devirt.c (ipa_devirt): Fix handling of speculative cals.
    	* ipa-fnsummary.c (analyze_function_body): Likewise.
    	* ipa-inline.c (speculation_useful_p): Use new speculative call API.
    	* ipa-profile.c (dump_histogram): Fix formating.
    	(ipa_profile_generate_summary): Watch for overflows.
    	(ipa_profile): Do not require probablity to be 1/2; update to new API.
    	* ipa-prop.c (ipa_make_edge_direct_to_target): Update to new API.
    	(update_indirect_edges_after_inlining): Update to new API.
    	* ipa-utils.c (ipa_merge_profiles): Rewrite merging of speculative call
    	profiles.
    	* profile-count.h: (profile_probability::adjusted): New.
    	* tree-inline.c (copy_bb): Update to new speculative call API; fix
    	updating of profile.
    	* value-prof.c (gimple_ic_transform): Rename to ...
    	(dump_ic_profile): ... this one; update dumping.
    	(stream_in_histogram_value): Fix formating.
    	(gimple_value_profile_transformations): Update.
    
    gcc/testsuite/ChangeLog:
    
    2020-01-28  Jan Hubicka  <hubicka@ucw.cz>
    
    	* g++.dg/tree-prof/indir-call-prof.C: Update template.
    	* gcc.dg/tree-prof/crossmodule-indircall-1.c: Add more targets.
    	* gcc.dg/tree-prof/crossmodule-indircall-1a.c: Add more targets.
    	* gcc.dg/tree-prof/indir-call-prof.c: Update template.
Comment 9 Xionghu Luo (luoxhu@gcc.gnu.org) 2022-05-13 09:42:57 UTC
I have a testcase ICE at:

external/com_google_protobuf/src/google/protobuf/message_lite.h:515:68: internal compiler error: Segmentation fault
0xde2816 crash_signal
        ../../gcc/toplev.c:328
0xe82370 copy_bb
        ../../gcc/tree-inline.c:2204
0xe84afa copy_cfg_body
        ../../gcc/tree-inline.c:3022
0xe855ea copy_body
        ../../gcc/tree-inline.c:3270
0xe8945b expand_call_inline
        ../../gcc/tree-inline.c:5061
0xe8a055 gimple_expand_calls_inline
        ../../gcc/tree-inline.c:5251
0xe8a831 optimize_inline_calls(tree_node*)
        ../../gcc/tree-inline.c:5424
0xb976ea inline_transform(cgraph_node*)
        ../../gcc/ipa-inline-transform.c:736
0xd1a147 execute_one_ipa_transform_pass
        ../../gcc/passes.c:2233
0xd1a2a1 execute_all_ipa_transforms(bool)
        ../../gcc/passes.c:2272
0x901809 cgraph_node::expand()
        ../../gcc/cgraphunit.c:2293
0x901e4a expand_all_functions
        ../../gcc/cgraphunit.c:2471
0x9028dd symbol_table::compile()
        ../../gcc/cgraphunit.c:2822
0x834fbc lto_main()
        ../../gcc/lto/lto.c:653


tree-inline.c:2204

2204:    cgraph_edge *indirect = old_edge->speculative_call_indirect_edge ();
2205:    profile_count indir_cnt = indirect->count;

the returned indirect is 0 caused assert on 2205.



(gdb) p old_edge->caller->debug()
_ZNK6google8protobuf11MessageLite23IsInitializedWithErrorsEv/15805768 (IsInitializedWithErrors) @0x7ffff6d44438
  Type: function definition analyzed
  Visibility: external public visibility_specified visibility:hidden
  References: _ZNK4trpc15RequestProtocol13IsInitializedEv/15470318 (addr) (speculative)
  Referring:
  Function IsInitializedWithErrors/15805768 is inline copy in OnExtendedInfosReceive/3878638
  Availability: local
  Unit id: 1201
  Function flags: count:26415 (adjusted) first_run:577 body local hot
  Called by: _ZN7yottadb2ds18BoundedReadWatcher22OnExtendedInfosReceiveERKSs/3878638 (inlined) (26415 (adjusted),1.00
per call) (can throw external)
  Calls: _ZNK6google8protobuf11MessageLite29LogInitializationErrorMessageEv/15806151 (0 (guessed),0.00 per call) (can
throw external) _ZNK7yottadb2ds28AppendLogRequestExtendedInfo13IsInitializedEv.constprop.0/16350633 (speculative) (inl
ined) (12547 (adjusted),0.47 per call) (can throw external) _ZNK7yottadb2ds28AppendLogRequestExtendedInfo13IsInitializ
edEv.constprop.0/16375492 (inlined) (indirect_inlining) (13868 (adjusted),0.52 per call) (can throw external)
$84 = void
(gdb) p old_edge->callee->debug()
_ZNK7yottadb2ds28AppendLogRequestExtendedInfo13IsInitializedEv.constprop.0/16350633 (IsInitialized.constprop) @0x7ffff
6d44b40
  Type: function definition analyzed
  Visibility: artificial
  References:
  Referring:
  Read from file: db_server.ltrans32.o
  Function IsInitialized.constprop/16350633 is inline copy in OnExtendedInfosReceive/3878638
  Availability: local
  Unit id: 116
  Function flags: count:12547 (adjusted) first_run:8235 body local icf_merged nonfreeing_fn
  Called by: _ZNK6google8protobuf11MessageLite23IsInitializedWithErrorsEv/15805768 (speculative) (inlined) (12547 (adj
usted),0.47 per call) (can throw external)
  Calls:


In wpa.079i.inline, it has TWO *polymorphic indirect call* speculative targets, I wrote a case like it but passed.

_ZNK6google8protobuf11MessageLite23IsInitializedWithErrorsEv/15805768 (IsInitializedWithErrors) @0x7efdc479a2d0
  Type: function definition analyzed
  Visibility: prevailing_def_ironly
  previous sharing asm name: 16375490
  References: _ZNK4trpc15RequestProtocol13IsInitializedEv/15470318 (addr) (speculative) _ZNK7yottadb3rpc17RunCommandRequest13IsInitializedEv/9954194 (addr) (speculative)
  Referring:
  Read from file: bazel-out/k8-dbg/bin/external/com_google_protobuf/libprotobuf_lite.a
  Availability: local
  Profile id: 19598949
  Unit id: 1200
  Function flags: count:1072 (adjusted) first_run:577 local
  Called by: _ZN6google8protobuf11MessageLite9ParseFromILNS1_10ParseFlagsE1ESsEEbRKT0_/16456195 (1824663 (estimated locally),0.00 per call) (can throw external) _ZN6google8protobuf11MessageLite9ParseFromILNS1_10ParseFlagsE1EPNS0_2io19ZeroCopyInputStreamEEEbRKT0_/15806727 (14 (adjusted),1.00 per call) (can throw external) _ZN6google8protobuf11MessageLite9ParseFromILNS1_10ParseFlagsE1ESsEEbRKT0_/15806733 (1006 (adjusted),1.00 per call) (can throw external) _ZN6google8protobuf11MessageLite9ParseFromILNS1_10ParseFlagsE1ENS0_11StringPieceEEEbRKT0_/15806735 (52 (precise),1.00 per call) (can throw external)
  Calls: _ZNK7yottadb2ds28AppendLogRequestExtendedInfo13IsInitializedEv.constprop.0/16365519 (speculative) (inlined) (456 (adjusted),0.43 per call) (can throw external) _ZNK7yottadb2ds28AppendLogRequestExtendedInfo13IsInitializedEv.constprop.0/16365518 (speculative) (inlined) (509 (adjusted),0.47 per call) (can throw external) _ZNK6google8protobuf11MessageLite29LogInitializationErrorMessageEv/15806151 (0 (guessed),0.00 per call) (can throw external)
   Polymorphic indirect call of type const struct MessageLite token:8(speculative) (106 (adjusted),0.10 per call) (can throw external)  of param:0 Num speculative call targets: 2
    Outer type (dynamic):struct MessageLite (or a derived type) offset 0


The only other difference is IsInitialized.constprop is *indirect_inlining* into caller, it seems NOT easy to reduce protobuf to a small case, any clue to fix it? Thanks.
@Honza
Comment 10 Xionghu Luo (luoxhu@gcc.gnu.org) 2022-05-13 10:07:34 UTC
And the Profile id of that node is streamed to many objects after lto partition:

grep --  "19598949" **
db_server.ltrans0.000i.cgraph:  Profile id: 19598949
db_server.ltrans0.000i.cgraph:  Profile id: 19598949
db_server.ltrans0.000i.cgraph:  Profile id: 19598949
db_server.ltrans0.079i.inline:  Profile id: 19598949
db_server.ltrans0.079i.inline:  Profile id: 19598949
db_server.ltrans12.000i.cgraph:  Profile id: 19598949
db_server.ltrans12.000i.cgraph:  Profile id: 19598949
db_server.ltrans12.000i.cgraph:  Profile id: 19598949
db_server.ltrans14.000i.cgraph:  Profile id: 19598949
db_server.ltrans26.000i.cgraph:  Profile id: 19598949
db_server.ltrans26.000i.cgraph:  Profile id: 19598949
db_server.ltrans26.000i.cgraph:  Profile id: 19598949
db_server.ltrans31.000i.cgraph:  Profile id: 19598949
db_server.ltrans32.000i.cgraph:  Profile id: 19598949
db_server.wpa.000i.cgraph:  Profile id: 19598949
db_server.wpa.001i.lto-link:  Profile id: 19598949
db_server.wpa.003i.lto-partition:  Profile id: 19598949
db_server.wpa.070i.whole-program:  Profile id: 19598949
db_server.wpa.071i.profile_estimate:  Profile id: 19598949
db_server.wpa.072i.icf:  Profile id: 19598949
db_server.wpa.073i.devirt:  Profile id: 19598949
db_server.wpa.074i.cp:  Profile id: 19598949
db_server.wpa.075i.sra:  Profile id: 19598949
db_server.wpa.078i.fnsummary:  Profile id: 19598949
db_server.wpa.079i.inline:  Profile id: 19598949
db_server.wpa.080i.pure-const:  Profile id: 19598949
db_server.wpa.080i.pure-const:  Profile id: 19598949
db_server.wpa.080i.pure-const:  Profile id: 19598949
db_server.wpa.080i.pure-const:  Profile id: 19598949
db_server.wpa.082i.static-var:  Profile id: 19598949
db_server.wpa.082i.static-var:  Profile id: 19598949