On Mon, May 31, 2021 at 7:30 PM apinski--- via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> From: Andrew Pinski <apin...@marvell.com>
>
> The problem here is we don't have an assignment type any more
> for empty structs as they were removed during gimplifcation.
> This adds a special case where the assignment var does not exist
> and the return decl is empty typed.
>
> OK? Tested on aarch64-linux-gnu with no regressions.

OK.

Richard.

> Thanks,
> Andrew Pinski
>
> changes since v1:
> v2: Use is_empty_type instead of zero-sized type.
>
>         PR tree-opt/95481
> gcc/ChangeLog:
>         * tree-tailcall.c (find_tail_calls): Handle empty typed
>         return decls.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/tailcall-10.c: New test.
>         * gcc.dg/tree-ssa/tailcall-11.c: New test.
>         * gcc.dg/tree-ssa/tailcall-12.c: New test.
>         * gcc.dg/tree-ssa/tailcall-13.c: New test.
>         * gcc.dg/tree-ssa/tailrecursion-8.c: New test.
> ---
>  gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c     | 12 ++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c     | 12 ++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c     | 12 ++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c     | 15 +++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c | 11 +++++++++++
>  gcc/tree-tailcall.c                             |  6 ++++--
>  6 files changed, 66 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c
> new file mode 100644
> index 00000000000..484dcc125fc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-10.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-tailc-details" } */
> +
> +struct A {};
> +
> +struct A goo(void);
> +struct A foo(void)
> +{
> +  return goo();
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c
> new file mode 100644
> index 00000000000..36e441775ff
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-11.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-tailc-details" } */
> +
> +struct A {};
> +
> +void goo(void);
> +struct A foo(void)
> +{
> +  goo();
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c
> new file mode 100644
> index 00000000000..0eeb3ab2794
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-12.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-tailc-details" } */
> +
> +struct A {};
> +
> +struct A goo(void);
> +void foo(void)
> +{
> +  goo();
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c
> new file mode 100644
> index 00000000000..855b3312ef4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-13.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-tailc-details" } */
> +
> +struct A {};
> +struct B{};
> +
> +struct B goo(void);
> +struct A foo(void)
> +{
> +  struct A a;
> +  goo();
> +  return a;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c 
> b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c
> new file mode 100644
> index 00000000000..ecde499a06b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-8.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -foptimize-sibling-calls -fdump-tree-tailr1-details" } 
> */
> +
> +struct A {};
> +
> +struct A foo()
> +{
> +  return foo();
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 1 "tailr1"} 
> } */
> diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
> index e866f7272ed..a4d31c90c49 100644
> --- a/gcc/tree-tailcall.c
> +++ b/gcc/tree-tailcall.c
> @@ -710,9 +710,11 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
>    ret_var = gimple_return_retval (as_a <greturn *> (stmt));
>
>    /* We may proceed if there either is no return value, or the return value
> -     is identical to the call's return.  */
> +     is identical to the call's return or if the return decl is an empty type
> +     variable and the call's return was not assigned. */
>    if (ret_var
> -      && (ret_var != ass_var))
> +      && (ret_var != ass_var
> +         && !(is_empty_type (TREE_TYPE (ret_var)) && !ass_var)))
>      return;
>
>    /* If this is not a tail recursive call, we cannot handle addends or
> --
> 2.17.1
>

Reply via email to