On Tue, 22 Jun 2021, Jakub Jelinek wrote:

> On Mon, Jun 14, 2021 at 11:24:22PM -0400, Jason Merrill via Gcc-patches wrote:
> > The x86_64 psABI says that an empty class isn't passed or returned in 
> > memory or
> > registers, so we shouldn't set %eax in this function.  Is this a reasonable
> > place to implement that?  Another possibility would be to remove the hack to
> > prevent i386.c:function_value_64 from returning NULL in this case and fix 
> > the
> > callers to deal, but that seems like more work.
> > 
> > The df-scan hunk catches the case where we look at a 0-length reg and build
> > a range the length of unsigned int, which happened before I changed
> > assign_parms to match expand_function_end.
> 
> The assign_params change unfortunately breaks e.g. the following testcase.
> The problem is that some passes (e.g. subreg lowering but assign_parms
> comments also talk about delayed slot scheduling) rely on crtl->return_rtx
> not to contain pseudo registers, and the assign_parms change results
> in the pseudo in there not being replaced with a hard register.
> 
> The following patch instead clears the crtl->return_rtx if a function
> returns TYPE_EMPTY_P structure, that way (use (pseudo)) is not emitted
> into the IL and it is treated like more like functions returning void.
> 
> I've also changed the effective target on the empty-class1.C testcase, so
> that it doesn't fail on x86_64-linux with -m32 testing.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.
 
> 2021-06-22  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR middle-end/101160
>       * function.c (assign_parms): For decl_result with TYPE_EMPTY_P type
>       clear crtl->return_rtx instead of keeping it referencing a pseudo.
> 
>       * g++.target/i386/empty-class1.C: Require lp64 effective target
>       instead of x86_64-*-*.
>       * g++.target/i386/empty-class2.C: New test.
> 
> --- gcc/function.c.jj 2021-06-22 10:04:46.000000000 +0200
> +++ gcc/function.c    2021-06-22 11:30:36.615264498 +0200
> @@ -3821,17 +3821,22 @@ assign_parms (tree fndecl)
>        tree decl_result = DECL_RESULT (fndecl);
>        rtx decl_rtl = DECL_RTL (decl_result);
>  
> -      if ((REG_P (decl_rtl)
> -        ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
> -        : DECL_REGISTER (decl_result))
> -       /* Unless the psABI says not to.  */
> -       && !TYPE_EMPTY_P (TREE_TYPE (decl_result)))
> +      if (REG_P (decl_rtl)
> +       ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
> +       : DECL_REGISTER (decl_result))
>       {
>         rtx real_decl_rtl;
>  
> -       real_decl_rtl = targetm.calls.function_value (TREE_TYPE (decl_result),
> -                                                     fndecl, true);
> -       REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
> +       /* Unless the psABI says not to.  */
> +       if (TYPE_EMPTY_P (TREE_TYPE (decl_result)))
> +         real_decl_rtl = NULL_RTX;
> +       else
> +         {
> +           real_decl_rtl
> +             = targetm.calls.function_value (TREE_TYPE (decl_result),
> +                                             fndecl, true);
> +           REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
> +         }
>         /* The delay slot scheduler assumes that crtl->return_rtx
>            holds the hard register containing the return value, not a
>            temporary pseudo.  */
> --- gcc/testsuite/g++.target/i386/empty-class1.C.jj   2021-06-22 
> 10:04:46.377208914 +0200
> +++ gcc/testsuite/g++.target/i386/empty-class1.C      2021-06-22 
> 11:37:53.463375502 +0200
> @@ -1,5 +1,5 @@
>  // PR target/88529
> -// { dg-do compile { target { c++11 && x86_64-*-* } } }
> +// { dg-do compile { target { c++11 && lp64 } } }
>  // { dg-additional-options -fdump-rtl-expand }
>  // { dg-final { scan-rtl-dump-not "set" "expand" } }
>  // The x86_64 psABI says that f() doesn't put the return value anywhere.
> --- gcc/testsuite/g++.target/i386/empty-class2.C.jj   2021-06-22 
> 11:34:53.422805115 +0200
> +++ gcc/testsuite/g++.target/i386/empty-class2.C      2021-06-22 
> 11:35:34.048257864 +0200
> @@ -0,0 +1,20 @@
> +// PR middle-end/101160
> +// Test passing aligned empty aggregate
> +// { dg-do compile }
> +// { dg-options "-O2" }
> +// { dg-additional-options "-Wno-psabi" { target { { i?86-*-* x86_64-*-* } 
> && ilp32 } } }
> +
> +struct S { union {} a; } __attribute__((aligned));
> +
> +S
> +foo (S arg)
> +{
> +  return arg;
> +}
> +
> +void
> +bar (void)
> +{
> +  S arg;
> +  foo (arg);
> +}
> 
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to