https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92599
--- Comment #4 from Xiong Hu XS Luo <luoxhu at cn dot ibm.com> --- (In reply to Xiong Hu XS Luo from comment #3) > (In reply to Martin Liška from comment #2) > > So we ICE at the end of cgraph_edge::speculative_call_info: > > (gdb) p ref > > $4 = <ipa_ref* 0x0> > > > > (gdb) p e > > $5 = <cgraph_edge* 0x7ffff769b5b0 (<cgraph_node * 0x7ffff74ac160 > > "ConvertASEToModelSurfaces.constprop"/113> -> <cgraph_node * 0x7ffff74ac420 > > "NumSurfaces"/115>)> > > (gdb) p e2 > > $6 = <cgraph_edge* 0x7ffff769b750 (<cgraph_node * 0x7ffff74ac160 > > "ConvertASEToModelSurfaces.constprop"/113> -> <cgraph_node * 0x0>)> > > > > As seen the edge is within idRenderModelStatic class. > > I bet the problem is the ODR warning message, the class is polymorphic in > > one TU, and normal class in another one. > > Seems side effect in indirect->set_call_stmt. > The "ref" is changed in recursive call line "indirect->set_call_stmt > (new_stmt, false)", it will call resolve_speculation to redirect one of it's > polymorphic call > ConvertASEToModelSurfaces/2 => FindMaterial/45, ref->remove_reference will > the related reference, then ref will be pointed to another reference, then > the followed "ref->stmt = new_stmt" will update wrong stmt to the original > reference. > > p *ref > $378 = {referring = 0x3fffb55f10e0, referred = 0x3fffb55f09d8, stmt = > 0x3fffb7f71440, lto_stmt_uid = 10, referred_index = 1, use = IPA_REF_ADDR, > speculative = 1 > > After returning from indirect->set_call_stmt (new_stmt, false): > > p *ref > $380 = {referring = 0x3fffb55f10e0, referred = 0x3fffb55f0ca8, stmt = > 0x3fffb7f713b0, lto_stmt_uid = 6, referred_index = 1, use = IPA_REF_ADDR, > speculative = 1} > > (gdb) pedge direct > $381 = 0x3fffb5560498 "ConvertASEToModelSurfaces.constprop/113" > $382 = 0x3fffb53d78a0 "FindMaterial/116" > (gdb) ps new_stmt > FindMaterial (_6); > ps ref->stmt > # .MEM = VDEF <.MEM> > OBJ_TYPE_REF(_5;(struct idRenderModelStatic)this_3(D)->1) (this_3(D)); > > > How about patch candidate as below? Or check the ref->speculative is true > after return from indirect->set_call_stmt? Not "ref->speculative", should be indirect->speculative as indirect edge is removed speculative now, or lto_stmt_uid is more reliable? (gdb) p *indirect $385 = {count = {static n_bits = 61, static max_count = 2305843009213693950, static uninitialized_count = 2305843009213693951, m_val = 406913472214181285, m_quality = AFDO}, caller = 0xa5a5a5a5a5a5a5a5, callee = 0xa5a5a5a5a5a5a5a5, prev_caller = 0xa5a5a5a5a5a5a5a5, next_caller = 0xa5a5a5a5a5a5a5a5, prev_callee = 0xa5a5a5a5 a5a5a5a5, next_callee = 0xa5a5a5a5a5a5a5a5, call_stmt = 0xa5a5a5a5a5a5a5a5, indirect_info = 0xa5a5a5a5a5a5a5a5, aux = 0xa5a5a5a5a5a5a5a5, inline_failed = 2779096485, lto_stmt_uid = 2779096485, indirect_inlining_edge= 1, indirect_unknown_callee = 0, call_stmt_cannot_inline_p = 1, can_throw_external = 0, speculative = 0, in_polymorphic_cdtor = 1, m_uid = -1515870811, m_summary_id = -1515870811}