On 2020-11-23 09:20, Richard Biener wrote: > On Sun, Nov 22, 2020 at 5:38 PM J.W. Jagersma <jwjager...@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.