I see the following ICE, it's reduced from icewm package: $ cat 1.ii class YWMApp { public: YWMApp(const char *); }; class YIcon { public: static int getIcon(const char *); }; YWMApp::YWMApp(const char *) { YIcon::getIcon(""); } char main_overrideTheme; main() { YWMApp app(&main_overrideTheme); } $ cat 2.ii class mstring { public: int compareTo(const mstring &) const; }; int mstring::compareTo(const mstring &) const {} class refcounted { public: virtual void __destroy(); }; class YIcon; template < class > class ref { YIcon *ptr; public: ~ref() { ptr->__destroy(); } }; class upath { public: upath(const char *); mstring path() { return fPath; } mstring fPath; }; int cacheFind_r; class YIcon : public refcounted { ref< YIcon > getIcon(const char *); int cacheFind(upath); public: ref< YIcon > *getItemPtr(); } iconCache; int YIcon::cacheFind(upath name) { ref< YIcon > __trans_tmp_2; while (cacheFind_r) { { __trans_tmp_2 = *getItemPtr(); } ref< YIcon > found = __trans_tmp_2; mstring __trans_tmp_1; name.path().compareTo(__trans_tmp_1); } } ref< YIcon > YIcon::getIcon(const char *name) { cacheFind(name); } $ g++ -O2 -fPIC 1.ii 2.ii -flto=16 1.ii:11:1: warning: ISO C++ forbids declaration of ‘main’ with no type [-Wreturn-type] 11 | main() { YWMApp app(&main_overrideTheme); } | ^~~~ 2.ii: In member function ‘int mstring::compareTo(const mstring&) const’: 2.ii:5:48: warning: no return statement in function returning non-void [-Wreturn-type] 5 | int mstring::compareTo(const mstring &) const {} | ^ 2.ii: In destructor ‘ref< <template-parameter-1-1> >::~ref()’: 2.ii:16:15: warning: invalid use of incomplete type ‘class YIcon’ 16 | ~ref() { ptr->__destroy(); } | ^~ 2.ii:11:7: note: forward declaration of ‘class YIcon’ 11 | class YIcon; | ^~~~~ 2.ii: In member function ‘int YIcon::cacheFind(upath)’: 2.ii:42:1: warning: no return statement in function returning non-void [-Wreturn-type] 42 | } | ^ 2.ii: In member function ‘ref<YIcon> YIcon::getIcon(const char*)’: 2.ii:43:66: warning: no return statement in function returning non-void [-Wreturn-type] 43 | ref< YIcon > YIcon::getIcon(const char *name) { cacheFind(name); } | ^ 1.ii:7:14: warning: ‘getIcon’ violates the C++ One Definition Rule [-Wodr] 7 | static int getIcon(const char *); | ^ 2.ii:43:14: note: ‘getIcon’ was previously declared here 43 | ref< YIcon > YIcon::getIcon(const char *name) { cacheFind(name); } | ^ 2.ii:43:14: note: code may be misoptimized unless ‘-fno-strict-aliasing’ is used during IPA pass: inline 2.ii: In function ‘getIcon.constprop.isra’: 2.ii:43:14: internal compiler error: in gimple_phi_arg, at gimple.h:4406 43 | ref< YIcon > YIcon::getIcon(const char *name) { cacheFind(name); } | ^ 0x639113 gimple_phi_arg /home/marxin/Programming/gcc/gcc/gimple.h:4406 0x639113 gimple_phi_arg /home/marxin/Programming/gcc/gcc/gimple.h:4414 0x639113 gimple_phi_arg_def /home/marxin/Programming/gcc/gcc/gimple.h:4457 0x639113 walk_ssa_copies /home/marxin/Programming/gcc/gcc/ipa-polymorphic-call.c:835 0xac7f71 ipa_polymorphic_call_context::ipa_polymorphic_call_context(tree_node*, tree_node*, gimple*, tree_node**) /home/marxin/Programming/gcc/gcc/ipa-polymorphic-call.c:898 0xa00ed6 possible_polymorphic_call_targets(tree_node*, gimple*, bool*, void**) /home/marxin/Programming/gcc/gcc/ipa-utils.h:134 0xa00ed6 gimple_fold_call /home/marxin/Programming/gcc/gcc/gimple-fold.c:4348 0xa0176b fold_stmt_1 /home/marxin/Programming/gcc/gcc/gimple-fold.c:5112 0xd5dea6 fold_marked_statements /home/marxin/Programming/gcc/gcc/tree-inline.c:5288 0xd6cbd1 optimize_inline_calls(tree_node*) /home/marxin/Programming/gcc/gcc/tree-inline.c:5369 0x15fac04 inline_transform(cgraph_node*) /home/marxin/Programming/gcc/gcc/ipa-inline-transform.c:720 0xc0eeaa execute_one_ipa_transform_pass /home/marxin/Programming/gcc/gcc/passes.c:2231 0xc0eeaa execute_all_ipa_transforms(bool) /home/marxin/Programming/gcc/gcc/passes.c:2270 0x897561 cgraph_node::expand() /home/marxin/Programming/gcc/gcc/cgraphunit.c:2189 0x89853b expand_all_functions /home/marxin/Programming/gcc/gcc/cgraphunit.c:2335 0x89853b symbol_table::compile() /home/marxin/Programming/gcc/gcc/cgraphunit.c:2685 0x7f49e9 lto_main() /home/marxin/Programming/gcc/gcc/lto/lto.c:658
__trans_tmp_2$ptr_16 = PHI <> when inlining fold_marked_stmts prunes dead EH edges immediately but that causes things like the above where IPA devirt now walking the SSA use-def chain. fold_marked_stmts needs to first fold and _then_ purge edges like so many other passes do. The alternative would be to use a bottom-up walk of the CFG but I guess that's too intricated there.
Oh, it's not there but #8 0x00000000011ba073 in expand_call_inline ( bb=<basic_block 0x7ffff663b4e0 (11)>, stmt=<gimple_call 0x7ffff6641080>, id=0x7fffffffd6e0) at /tmp/trunk/gcc/tree-inline.c:5160 5160 gimple_purge_dead_eh_edges (return_block); does the purging.
Created attachment 47360 [details] patch I am testing the attached. The testcase seems to be too much reduced to be useful for the testsuite.
Author: rguenth Date: Wed Nov 27 08:52:17 2019 New Revision: 278757 URL: https://gcc.gnu.org/viewcvs?rev=278757&root=gcc&view=rev Log: 2019-11-27 Richard Biener <rguenther@suse.de> PR middle-end/92674 * tree-inline.c (expand_call_inline): Delay purging EH/abnormal edges and instead record blocks in bitmap. (gimple_expand_calls_inline): Adjust. (fold_marked_statements): Delay EH cleanup until all folding is done. (optimize_inline_calls): Do EH/abnormal cleanup for calls after inlining finished. Modified: trunk/gcc/ChangeLog trunk/gcc/tree-inline.c
Fixed on trunk sofar.
The releases/gcc-9 branch has been updated by Richard Guenther <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:c6480e01fc53f0e9822ec1694239155756430952 commit r9-8230-gc6480e01fc53f0e9822ec1694239155756430952 Author: Richard Biener <rguenther@suse.de> Date: Fri Feb 14 09:10:48 2020 +0100 middle-end/92674 delay purging EH edges when folding during inlining 2020-02-14 Richard Biener <rguenther@suse.de> Backport from mainline 2019-11-27 Richard Biener <rguenther@suse.de> PR middle-end/92674 * tree-inline.c (expand_call_inline): Delay purging EH/abnormal edges and instead record blocks in bitmap. (gimple_expand_calls_inline): Adjust. (fold_marked_statements): Delay EH cleanup until all folding is done. (optimize_inline_calls): Do EH/abnormal cleanup for calls after inlining finished.
The releases/gcc-8 branch has been updated by Richard Guenther <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:8a7f319cad03b87020b788c0779cf49a2718e12e commit r8-10029-g8a7f319cad03b87020b788c0779cf49a2718e12e Author: Richard Biener <rguenther@suse.de> Date: Fri Feb 14 09:10:48 2020 +0100 middle-end/92674 delay purging EH edges when folding during inlining 2020-02-14 Richard Biener <rguenther@suse.de> Backport from mainline 2019-11-27 Richard Biener <rguenther@suse.de> PR middle-end/92674 * tree-inline.c (expand_call_inline): Delay purging EH/abnormal edges and instead record blocks in bitmap. (gimple_expand_calls_inline): Adjust. (fold_marked_statements): Delay EH cleanup until all folding is done. (optimize_inline_calls): Do EH/abnormal cleanup for calls after inlining finished.
Fixed.