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 >