[PATCH v3 1/2] generate EH info for volatile asm statements (PR93981)

J.W. Jagersma jwjagersma@gmail.com
Mon Nov 30 16:47:25 GMT 2020


On 2020-11-23 09:20, Richard Biener wrote:
> On Sun, Nov 22, 2020 at 5:38 PM J.W. Jagersma <jwjagersma@gmail.com> wrote:
>>
>> On 2020-11-21 12:27, J.W. Jagersma wrote:
>>> ...
>>> Another idea I had is to introduce a new operand modifier, eg. '-', which
>>> would signify that the output *must* be considered clobbered on exception,
>>> and it would be an error if a copy is not possible.  Then the meaning of '+'
>>> can be extended to say that the output must be valid regardless of whether an
>>> exception occured or not.  Modifier '=' would mean the same as '+' with the
>>> additional implication that it is okay to eliminate earlier assignments, so
>>> that its value on the EH edge would be undefined.
>>
>> I've been working on implementing this, but I ran into an issue:
>>
>> First of all, in the first version of this patch I had to make sure that
>> debug stmts were inserted across the fallthrough edge, so that they don't
>> appear at the end a basic block.  I was surprised to find that this is no
>> longer necessary.
>>
>> Next I discovered that the following test case fails (returns -1):
>>
>>     int f ()
>>     {
>>       int i = 0;
>>       try { asm ("mov %0, 1; ud2" : "+r" (i)); }
>>       catch (...) { }
>>       return i - 1;
>>     }
>>
>> And this does succeed with a memory operand.
>>
>> It seems that something changed in the past few months, and now asm register
>> outputs are already being assigned via a temporary variable, somewhere.  Does
>> anyone know where that might be?
> 
> It's likely out-of SSA / RTL expansion inserting a bogus copy or doing
> coalescing on the EH edge.  Semantics of throwing asm stmts need to be
> honored there.
> 
> Richard.

Quick update.  I have a mostly working implementation now, the only case where
it fails is when an asm clobbers all callee-saved registers.  In this one case
the output is not available on the exception edge.  However this same case does
work correctly with an 'asm goto' that throws.

The problem I think is in lra_process_new_insns (lra.c:1878) where the condition
to insert new insns across edges is "JUMP_P (insn)", but this should happen for
throwing asms as well.  I figured "insn == BB_END (BLOCK_FOR_INSN (insn))" would
make sense but that causes all sorts of trouble (segfaults during bootstrap).

Would appreciate any advice on what to do here.


More information about the Gcc-patches mailing list