https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123111

--- Comment #8 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #7)
> Maybe for GCC 16, make_forwarders_with_degenerate_phis needs to be tuned
> down if the edge comes from an ifconvertable edge. just so we get a
> copy/constant on the edges there.

This is what I went for in the end:
```
/* Returns true if edge E comes from a possible ifconvertable branch.
   That is:
   ```
   BB0:
   if (a) goto BB1; else goto BB2;
   BB1:
   BB2:
   ```
   Returns true for the edge from BB0->BB2 or BB1->BB2.
   This function assumes we only have one middle block.
   And the middle block is empty. */

static bool
ifconvertable_edge (edge e)
{
  basic_block bb2 = e->dest;
  basic_block bb0 = e->src;
  basic_block bb1 = nullptr, rbb1;
  if (e->src == e->dest)
    return false;
  if (EDGE_COUNT (bb0->succs) > 2)
    return false;
  if (single_succ_p (bb0))
    {
      if (!single_pred_p (bb0))
        return false;
      /* The middle block can only be empty,
         otherwise the phis will be
         different anyways. */
      if (!empty_block_p (bb0))
        return false;
      bb1 = bb0;
      bb0 = single_pred (bb0);
      if (EDGE_COUNT (bb0->succs) != 2)
        return false;
    }

  /* If convertables are only for conditionals. */
  if (!is_a<gcond*>(*gsi_last_nondebug_bb (bb0)))
    return false;

  /* Find the other basic block.  */
  if (EDGE_SUCC (bb0, 0)->dest == bb2)
    rbb1 = EDGE_SUCC (bb0, 1)->dest;
  else if (EDGE_SUCC (bb0, 1)->dest == bb2)
    rbb1 = EDGE_SUCC (bb0, 0)->dest;
  else
    return false;

  /* If we already know bb1, then just test it. */
  if (bb1)
    return rbb1 == bb1;

  if (!single_succ_p (rbb1) || !single_pred_p (rbb1))
    return false;
  /* The middle block can only be empty,
     otherwise the phis will be
     different anyways. */
  if (!empty_block_p (rbb1))
    return false;

  return single_succ (rbb1) == bb2;
}
```

And then in make_forwarders_with_degenerate_phis skip the edge (in the original
loop) if that returns true and we were passed true.

This gets us back the code and fixes the other testcase too. And does not cause
any new x86_64 regressions.

Reply via email to