On Fri, Jun 13, 2025 at 10:05:14AM +0200, Jakub Jelinek wrote:
> On Fri, Jun 13, 2025 at 08:52:55AM +0100, Richard Sandiford wrote:
> > > 2025-06-12  Jakub Jelinek  <ja...@redhat.com>
> > >
> > >   * cfgexpand.cc (construct_init_block): If first_block isn't BB_RTL,
> > >   has any PHI nodes and false_edge->dest_idx before redirection is
> > >   different from make_single_succ_edge result's dest_idx, swap the
> > >   latter with the former last pred edge and their dest_idx members.
> > 
> > OK, thanks.  But now that there are two instances, I wonder if it would
> > be worth hiding this detail in a helper function?
> 
> Will try to come up with something incrementally if that is ok.

Here it is, so far lightly tested.  Ok for trunk if it passes full
bootstrap/regtest?

2025-06-13  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/120629
        * cfgexpand.cc (expand_split_edge): New function.
        (expand_gimple_cond, construct_init_block): Use it.

--- gcc/cfgexpand.cc.jj 2025-06-13 14:01:15.168637257 +0200
+++ gcc/cfgexpand.cc    2025-06-13 14:17:14.896303981 +0200
@@ -2830,6 +2830,31 @@ expand_remove_edge (edge e)
   remove_edge (e);
 }
 
+/* Split edge E during expansion and instead of creating a new
+   bb on that edge, add there BB.  FLAGS should be flags on the
+   new edge from BB to former E->dest.  */
+
+static void
+expand_split_edge (edge e, basic_block bb, int flags)
+{
+  unsigned int dest_idx = e->dest_idx;
+  basic_block dest = e->dest;
+  redirect_edge_succ (e, bb);
+  e = make_single_succ_edge (bb, dest, flags);
+  if ((dest->flags & BB_RTL) == 0
+      && phi_nodes (dest)
+      && e->dest_idx != dest_idx)
+    {
+      /* If there are any PHI nodes on dest, swap the new succ edge
+        with the one moved into false_edge's former position, so that
+        PHI arguments don't need adjustment.  */
+      edge e2 = EDGE_PRED (dest, dest_idx);
+      std::swap (e->dest_idx, e2->dest_idx);
+      std::swap (EDGE_PRED (dest, e->dest_idx),
+                EDGE_PRED (dest, e2->dest_idx));
+    }
+}
+
 
 /* A subroutine of expand_gimple_cond.  Given E, a fallthrough edge
    of a basic block where we just expanded the conditional at the end,
@@ -3013,8 +3038,7 @@ expand_gimple_cond (basic_block bb, gcon
 
   new_bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb);
   dest = false_edge->dest;
-  unsigned int dest_idx = false_edge->dest_idx;
-  redirect_edge_succ (false_edge, new_bb);
+  expand_split_edge (false_edge, new_bb, 0);
   false_edge->flags |= EDGE_FALLTHRU;
   new_bb->count = false_edge->count ();
   loop_p loop = find_common_loop (bb->loop_father, dest->loop_father);
@@ -3022,19 +3046,6 @@ expand_gimple_cond (basic_block bb, gcon
   if (loop->latch == bb
       && loop->header == dest)
     loop->latch = new_bb;
-  edge e = make_single_succ_edge (new_bb, dest, 0);
-  if ((dest->flags & BB_RTL) == 0
-      && phi_nodes (dest)
-      && e->dest_idx != dest_idx)
-    {
-      /* If there are any PHI nodes on dest, swap the new succ edge
-        with the one moved into false_edge's former position, so that
-        PHI arguments don't need adjustment.  */
-      edge e2 = EDGE_PRED (dest, dest_idx);
-      std::swap (e->dest_idx, e2->dest_idx);
-      std::swap (EDGE_PRED (dest, e->dest_idx),
-                EDGE_PRED (dest, e2->dest_idx));
-    }
   if (BARRIER_P (BB_END (new_bb)))
     BB_END (new_bb) = PREV_INSN (BB_END (new_bb));
   update_bb_for_insn (new_bb);
@@ -6538,7 +6549,7 @@ expand_gimple_basic_block (basic_block b
 static basic_block
 construct_init_block (void)
 {
-  basic_block init_block, first_block;
+  basic_block init_block;
   edge e = NULL;
   int flags;
 
@@ -6569,24 +6580,7 @@ construct_init_block (void)
   init_block->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
   add_bb_to_loop (init_block, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
   if (e)
-    {
-      unsigned int dest_idx = e->dest_idx;
-      first_block = e->dest;
-      redirect_edge_succ (e, init_block);
-      e = make_single_succ_edge (init_block, first_block, flags);
-      if ((first_block->flags & BB_RTL) == 0
-         && phi_nodes (first_block)
-         && e->dest_idx != dest_idx)
-       {
-         /* If there are any PHI nodes on dest, swap the new succ edge
-            with the one moved into false_edge's former position, so that
-            PHI arguments don't need adjustment.  */
-         edge e2 = EDGE_PRED (first_block, dest_idx);
-         std::swap (e->dest_idx, e2->dest_idx);
-         std::swap (EDGE_PRED (first_block, e->dest_idx),
-                    EDGE_PRED (first_block, e2->dest_idx));
-       }
-    }
+    expand_split_edge (e, init_block, flags);
   else
     make_single_succ_edge (init_block, EXIT_BLOCK_PTR_FOR_FN (cfun),
                           EDGE_FALLTHRU);


        Jakub

Reply via email to