https://gcc.gnu.org/g:08e803aa9becf407eb7ef7cf6af96e3bd0d02d38
commit r15-9193-g08e803aa9becf407eb7ef7cf6af96e3bd0d02d38 Author: Jakub Jelinek <ja...@redhat.com> Date: Fri Apr 4 08:59:51 2025 +0200 tailc: Use the IPA-VRP tail call hack even for pointers [PR119614] As the first two testcases show, even with pointers IPA-VRP can optimize return values from functions if they have singleton ranges into just the exact value, so we need to virtually undo that for tail calls similarly to integers and floats. The third test just adds check that it works even with floats (which it does). 2025-04-04 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/119614 * tree-tailcall.cc (find_tail_calls): Handle also pointer types in the IPA-VRP workaround. * c-c++-common/pr119614-1.c: New test. * c-c++-common/pr119614-2.c: New test. * c-c++-common/pr119614-3.c: New test. Diff: --- gcc/testsuite/c-c++-common/pr119614-1.c | 28 ++++++++++++++++++++++++++++ gcc/testsuite/c-c++-common/pr119614-2.c | 28 ++++++++++++++++++++++++++++ gcc/testsuite/c-c++-common/pr119614-3.c | 28 ++++++++++++++++++++++++++++ gcc/tree-tailcall.cc | 4 +++- 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/c-c++-common/pr119614-1.c b/gcc/testsuite/c-c++-common/pr119614-1.c new file mode 100644 index 000000000000..89105a317cb1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr119614-1.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/119614 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2" } */ + +volatile int v; + +[[gnu::noinline]] const char * +foo (int x) +{ + v += x; + return 0; +} + +const char * +bar (int x) +{ + if (x == 42) + [[gnu::musttail]] return foo (42); + [[gnu::musttail]] return foo (32); +} + +const char * +baz (int x) +{ + if (x == 5) + return foo (42); + return foo (32); +} diff --git a/gcc/testsuite/c-c++-common/pr119614-2.c b/gcc/testsuite/c-c++-common/pr119614-2.c new file mode 100644 index 000000000000..8833eeec8705 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr119614-2.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/119614 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2" } */ + +volatile int v; + +[[gnu::noinline]] const char * +foo (int x) +{ + v += x; + return (const char *) -42; +} + +const char * +bar (int x) +{ + if (x == 42) + [[gnu::musttail]] return foo (42); + [[gnu::musttail]] return foo (32); +} + +const char * +baz (int x) +{ + if (x == 5) + return foo (42); + return foo (32); +} diff --git a/gcc/testsuite/c-c++-common/pr119614-3.c b/gcc/testsuite/c-c++-common/pr119614-3.c new file mode 100644 index 000000000000..59ed36b0ab53 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr119614-3.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/119614 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2" } */ + +volatile int v; + +[[gnu::noinline]] double +foo (int x) +{ + v += x; + return 0.5; +} + +double +bar (int x) +{ + if (x == 42) + [[gnu::musttail]] return foo (42); + [[gnu::musttail]] return foo (32); +} + +double +baz (int x) +{ + if (x == 5) + return foo (42); + return foo (32); +} diff --git a/gcc/tree-tailcall.cc b/gcc/tree-tailcall.cc index 477729ca2137..c5fac5152254 100644 --- a/gcc/tree-tailcall.cc +++ b/gcc/tree-tailcall.cc @@ -1036,7 +1036,9 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail, && TREE_CONSTANT (ret_var)) if (tree type = gimple_range_type (call)) if (tree callee = gimple_call_fndecl (call)) - if ((INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type)) + if ((INTEGRAL_TYPE_P (type) + || SCALAR_FLOAT_TYPE_P (type) + || POINTER_TYPE_P (type)) && useless_type_conversion_p (TREE_TYPE (TREE_TYPE (callee)), type) && useless_type_conversion_p (TREE_TYPE (ret_var), type)