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

J.W. Jagersma jwjagersma@gmail.com
Tue Dec 1 17:02:01 GMT 2020


On 2020-11-30 17:47, J.W. Jagersma wrote:
> 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.

Just realized I can make it work by simply expanding throwing asms as jump
insns with no label.  I'm not sure about the specific semantic differences
between regular and jump insns, but this doesn't seem to have any negative
effects so far.

I will submit v4 after I finish running regression tests and writing docs and
changelogs.  Or if this is not an acceptable workaround, please let me know.


More information about the Gcc-patches mailing list