On Wed, 2023-11-15 at 04:26 +0800, Xi Ruoyao wrote:
> On Tue, 2023-11-14 at 20:46 +0800, chenglulu wrote:
> > 
> > 在 2023/11/14 下午5:55, Xi Ruoyao 写道:
> > > On Tue, 2023-11-14 at 17:45 +0800, Lulu Cheng wrote:
> > > > +      /* When function calls are made through call36, t0 register
> > > > will be
> > > > +        implicitly modified, so '-fno-ipa-ra' needs to be set
> > > > here.  */
> > > >         case CMODEL_MEDIUM:
> > > > +       if (HAVE_AS_SUPPORT_CALL36)
> > > > +         opts->x_flag_ipa_ra = 0;
> > > > +       break;
> > > Maybe we can add a (clobber (reg:P 12)) to the related insns
> > > instead?
> > > 
> > Sorry, this was modified in accordance with the call36 macro
> > instruction 
> > during the test.
> > I will use clobber, and add test cases.
> 
> There seems a better solution as suggested by the GCC internal doc. 
> Section 18.9.16 mentions -fipa-ra:
> 
>  -- Target Hook: bool TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
>      Set to true if each call that binds to a local definition
>      explicitly clobbers or sets all non-fixed registers modified by
>      performing the call.  That is, by the call pattern itself, or by
>      code that might be inserted by the linker (e.g. stubs, veneers,
>      branch islands), but not including those modifiable by the callee.
>      The affected registers may be mentioned explicitly in the call
>      pattern, or included as clobbers in CALL_INSN_FUNCTION_USAGE. The
>      default version of this hook is set to false.  The purpose of this
>      hook is to enable the fipa-ra optimization.
> 
> So we can add t0 into CALL_INSN_FUNCTION_USAGE of the call insn, like:
> 
> diff --git a/gcc/config/loongarch/loongarch.md 
> b/gcc/config/loongarch/loongarch.md
> index ea36542b1c3..96e7e98e6b3 100644
> --- a/gcc/config/loongarch/loongarch.md
> +++ b/gcc/config/loongarch/loongarch.md
> @@ -3274,7 +3274,14 @@ (define_expand "sibcall"
>                                           XEXP (target, 1),
>                                           operands[1]));
>    else
> -    emit_call_insn (gen_sibcall_internal (target, operands[1]));
> +    {
> +      rtx call = gen_sibcall_internal (target, operands[1]);
> +
> +      if (TARGET_CMODEL_MEDIUM && !REG_P (target))
> +     clobber_reg (&CALL_INSN_FUNCTION_USAGE (call),
> +                  gen_rtx_REG (Pmode, T0_REGNUM));
> +      emit_call_insn (call);
> +    }
>    DONE;
>  })
> 
> Likewise for sibcall_value.

Nope.  This does not work for

__attribute__((noinline)) void q() { asm ("":::"memory"); }
__attribute__((noinline)) static void t() { q(); }

int
main ()
{
  int x0 = 114514;

  asm("":"+r"(x0));
  t();
  if (x0 != 114514)
    __builtin_trap ();
}

Not sure why...

> 
> By the way we'd better have a command line switch to override the build-
> time check for assembler call36 support, because it makes writing test
> cases and inter-operating with different versions of assembler easier.
> 

-- 
Xi Ruoyao <xry...@xry111.site>
School of Aerospace Science and Technology, Xidian University

Reply via email to