Hi, the ipa-inline-transform ICE is caused by fact that devirt_benefit in ipa-inline-analysis is able to determine devirtualiation oppurtunity of call to b3, while the ipa-prop responsible for updating function body after inlining is not. This is because the later is missing code turning known constant into binfo.
Bootstrapped/regtested x86_64-linux, will commit this shortly. Honza PR tree-optimization/55683 * g++.dg/ipa/devirt-9.C: New testcase. * ipa-prop.c (try_make_edge_direct_virtual_call): Look into constants for binfo. Index: testsuite/g++.dg/ipa/devirt-9.C =================================================================== *** testsuite/g++.dg/ipa/devirt-9.C (revision 0) --- testsuite/g++.dg/ipa/devirt-9.C (revision 0) *************** *** 0 **** --- 1,30 ---- + /* { dg-do compile } */ + /* { dg-options "-O2 -fdump-ia-inline" } */ + double foo (); + struct B + { + bool b1 () { return b3 (); } + void b2 (); + virtual bool b3 (); + }; + struct C + { + C () {} + bool + c1 (float x, float y) + { + if (x != c3 || y != c4) + c2.b2 (); + return c2.b1 (); + } + B c2; + float c3, c4; + }; + + void + bar () + { + static C c; + c.c1 (60, (int) foo ()); + } + /* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target" "inline" } } */ Index: ipa-prop.c =================================================================== *** ipa-prop.c (revision 194584) --- ipa-prop.c (working copy) *************** try_make_edge_direct_virtual_call (struc *** 2223,2231 **** binfo = ipa_value_from_jfunc (new_root_info, jfunc); ! if (!binfo || TREE_CODE (binfo) != TREE_BINFO) return NULL; binfo = get_binfo_at_offset (binfo, ie->indirect_info->offset, ie->indirect_info->otr_type); if (binfo) --- 2223,2238 ---- binfo = ipa_value_from_jfunc (new_root_info, jfunc); ! if (!binfo) return NULL; + if (TREE_CODE (binfo) != TREE_BINFO) + { + binfo = gimple_extract_devirt_binfo_from_cst (binfo); + if (!binfo) + return NULL; + } + binfo = get_binfo_at_offset (binfo, ie->indirect_info->offset, ie->indirect_info->otr_type); if (binfo)