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

Reply via email to