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

Michael Matz <matz at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |matz at gcc dot gnu.org

--- Comment #9 from Michael Matz <matz at gcc dot gnu.org> ---
Just for completeness: I agree with Andrew that the initial code example in
comment #0 doesn't show any problem.  The edge from asmgoto to l0 doesn't cross
the scope of the variable, hence no cleanups should be run.  The cleanup
call that is there is from the edge that leaves the function scope before
return, and it's placed correctly.

But the example from comment #8 indeed shows a problem with asm-goto.  But it
may be impossible to fix.  That has to do with how we need to (possibly) split
critical edges, which changes label identity, which in turn might actually
be the thing that's required by the asmgoto.  Like in such situation:

----------
extern int printf (const char *, ...);
extern void doit(void *p);

void foo (int cond)
{
  {
    int x __attribute__((cleanup(doit)));
    if (cond)
      asm goto("# A %l0"::::out);
    else
      asm goto("# B %l0"::::out);
  }
  printf("...");
  out:
}
----------

The calls to doit need to be emitted on the two edges asm1->out and asm2->out,
but must _not_ be emitted on the fallthrough printf->out (of course, because
the cleanup was already done on the edge x-scope->printf).  The only
way to do that is by splitting those edges which introduces new labels:

{
  {
    int x;
    if (cond)
      asm goto("# A %l0"::::out1);
    else
      asm goto("# B %l0"::::out2);
    doit();
  }
  printf("...");
 out:
  return;
out1: doit(); goto out;
out2: doit(); goto out;
}

(In this easy example we could save ourself by realizing that the out1 and out2
code sequences are the same, and hence could get away with just emitting
one new label instead of two.  In general that's not possible.)

That's the CFG manipulation that needs happening.  The question is what
it does to the asmgoto: both now receive different labels, whereas before
they received the same.  If whatever the asm does relies on the identity of
these label then this will break things.

Now, asm gotos were specifically introduced to be able to jump to stuff,
not to capture the identity of labels/code-addresses (as is done for instance
in the linux kernel alternative mechanism), so it may be fine to do the edge
splitting and associated renaming of labels.  But that needs to be a conscious
decision.

Reply via email to