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 ();
             }

Reply via email to