Segher Boessenkool <seg...@kernel.crashing.org> writes: > Hi! > > On Thu, Feb 06, 2020 at 10:49:36AM +0800, Jiufu Guo wrote: >> > emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); >> > >> > for (i = 0; i < XVECLEN (operands[2], 0); i++) >> > { >> > rtx set = XVECEXP (operands[2], 0, i); >> > emit_move_insn (SET_DEST (set), SET_SRC (set)); >> > } >> > >> > ... and nothing in the rtl stream says that those return registers are >> > actually set by that call. Maybe we should use gen_call_value? Can we >> > ever be asked to return more than a single thing here? >> I was also thinking about using "gen_call_value" or "emit_clobber (r3)" >> which could generate rtl: "%3:DI=call [foo]" or "call [foo]; clobber >> r3". This could tell optimizer that %3 is changed. > > The problem with "call ; clobber r3" is that some set+use of a pseudo can > be moved between these, and then rnreg can rename that to r3 again. We > really need to show the call sets r3, in the general case (or that r3 is > live after the call, at least). Thanks! More careful thought You are right: set+use maybe able to move between "call ; clobber". "%3=call" is ok without this issue.
> >> While there are >> potential issues that untyped_call may change other registers. So, mark >> clobber for all touched registers maybe more safe. > > Well, we can derive what registers it sets, perhaps? What does x86 do > here? It does something, I know that, haven't looked much deeper yet > though :-) For x86, it is generates something like "%c=call": Ix86_Expand_call ((TARGET_FLOAT_RETURNS_IN_80387 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), operands[0], const0_rtx,... first argument of ix86_expand_call is 'set of call'. As comment of untyped_call of i386.md: /* In order to give reg-stack an easier job in validating two coprocessor registers as containing a possible return value, simply pretend the untyped call returns a complex long double value. For ppc, maybe %3:DI,%3:TI, %1SF... maybe set by untyped_call, right? And from trunk source code(builtins.c and .md for targets): for (i = 0; i < XVECLEN (operands[2], 0); i++) { rtx set = XVECEXP (operands[2], 0, i); emit_move_insn (SET_DEST (set), SET_SRC (set)); } Above code may means all registers in operands[2] are stored/moved to stack, those registers maybe altered. Any corrections? Thanks for your comments and sugguestions! Jiufu > > In general: this is not a problem for us only; some other archs may have > found a good solution already. > > > Segher