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

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
Interesting one.  Not that I think we previously handled this "correctly":

  <bb 2>:
  foo ();

  <bb 3>:
  p.0 = p;

  <bb 4>:
  D.1765 = vfork ();
  *p.0 = D.1765;
  return;

  <bb 5>:
  ABNORMAL_DISPATCHER (0);

so we keep p.0 in a register around the vfork call and only as we are lucky
and use eax which we need to spill around vfork it works.

The original testcase has the same issue and in GCC 6 was gimplified to

bar ()
{
  struct globals * ptr.0;
  int D.1766;

  foo (0);
  ptr.0 = ptr;
  {
    int pid;

    pid = vfork ();
    {
      if (pid < 0) goto <D.1769>; else goto <D.1770>;
      <D.1769>:
      foo (0);
      <D.1770>:
    }
    D.1766 = pid;
  }
  ptr.0->helper_pid = D.1766;


The only solution to fix the ICE I see is to dig into the RHS to find a
possible ECF_RETURNS_TWICE call before gimplifying the LHS in
gimplify_modify_expr and turn off ->into_ssa in that case.

Not sure if it would be ok to swap LHS and RHS gimplification here
(RHS is gimplified to a CALL_EXPR first, but at least its arguments
are already gimplified there).  I'll need to lookup the standard for
sequence points here.

Reply via email to