https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82831
--- Comment #4 from Martin Liška <marxin at gcc dot gnu.org> --- So problem is that in pass_reorder_blocks::execute we reorder blocks so that they are separated to cold and hot partitions. Then cleanup_cfg (CLEANUP_EXPENSIVE); is called (bb-reorder.c:2593) and we end here: 2324 static vec<basic_block> 2325 find_partition_fixes (bool flag_only) 2326 { 2327 basic_block bb; 2328 vec<basic_block> bbs_in_cold_partition = vNULL; 2329 vec<basic_block> bbs_to_fix = vNULL; 2330 hash_set<basic_block> set; 2331 2332 /* Callers check this. */ 2333 gcc_checking_assert (crtl->has_bb_partition); 2334 2335 find_bbs_reachable_by_hot_paths (&set); 2336 2337 FOR_EACH_BB_FN (bb, cfun) 2338 if (!set.contains (bb) 2339 && BB_PARTITION (bb) != BB_COLD_PARTITION) 2340 { 2341 if (flag_only) 2342 error ("non-cold basic block %d reachable only " 2343 "by paths crossing the cold partition", bb->index); 2344 else 2345 BB_SET_PARTITION (bb, BB_COLD_PARTITION); 2346 bbs_to_fix.safe_push (bb); 2347 bbs_in_cold_partition.safe_push (bb); 2348 } 2349 2350 return bbs_to_fix; 2351 } and we mark one BB in hot partition as COLD. That causes the ICE. What about something like this: diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 5a5ddbfcb6d..5c393efd164 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -506,6 +506,7 @@ ei_cond (edge_iterator ei, edge *p) insns. */ #define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */ #define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */ +#define CLEANUP_NO_PARTITIONING 128 /* Do not try to fix partitions. */ /* Return true if BB is in a transaction. */ diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index f7c1f4c971e..20e231739e3 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -2590,7 +2590,7 @@ pass_reorder_blocks::execute (function *fun) cfg_layout_initialize (CLEANUP_EXPENSIVE); reorder_basic_blocks (); - cleanup_cfg (CLEANUP_EXPENSIVE); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_NO_PARTITIONING); FOR_EACH_BB_FN (bb, fun) if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (fun)) diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 4734d3eae17..84756a542da 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -3011,7 +3011,8 @@ try_optimize_cfg (int mode) to detect and fix during edge forwarding, and in some cases is only visible after newly unreachable blocks are deleted, which will be done in fixup_partitions. */ - fixup_partitions (); + if ((mode & CLEANUP_NO_PARTITIONING) == 0) + fixup_partitions (); checking_verify_flow_info (); }