https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103270
--- Comment #2 from luoxhu at gcc dot gnu.org --- (In reply to Richard Biener from comment #1) > So you say this is a problem with loop header copying, that would mean the > issue is really latent and general, no? Header copying uses > gimple_duplicate_sese_region and has no own profile updating. I guess its > profile updating code isn't designed to cope with copying a region with > "side"-entries (we are ignoring the backedge here). Not sure if we can > somehow generally handle those (maybe we can learn from tracer or threader > here). > > Honza? Yes, it seems to be a general issue in gimple_duplicate_sese_region, the inner loop cfg was: 8 | 3<-- | \ | 5 4 And it is modified by ch_base::copy_headers->gimple_duplicate_sese_region to( entry edge is 8->3, exit edge is 3->4): 8 | 12 | 4<-- | | 3--- | 5 bb 12 is copied block from bb 3 as new preheader, bb 3 is rotated to be new exit of the loop, bb 3 and bb 12 are adjusted count to "total_count - entry_count" (354334800) and "entry_count"(719407024), at last bb 3 and bb 4 will be merged to one block by gimple_merge_blocks later by TODO_cleanup_cfg with much smaller count than preheader. gimple_duplicate_sese_region: if (total_count.initialized_p () && entry_count.initialized_p ()) { scale_bbs_frequencies_profile_count (region, n_region, total_count - entry_count, total_count); scale_bbs_frequencies_profile_count (region_copy, n_region, entry_count, total_count); } Obviously, region of bb 3's profile count shouldn't be decreased from "total_count" to "total_count - entry_count", it executes at every execution of the loop. Simply adjust it back to total_count and region_copy to entry_count will cause some other cases fail. And at the moment edge 3->4 is still not a backedge now?