Hi! 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).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 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. --- gcc/tree-tailcall.cc.jj 2025-04-02 20:02:24.303939759 +0200 +++ gcc/tree-tailcall.cc 2025-04-03 22:10:57.018048523 +0200 @@ -1036,7 +1036,9 @@ find_tail_calls (basic_block bb, struct && 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) --- gcc/testsuite/c-c++-common/pr119614-1.c.jj 2025-04-03 22:22:09.060828085 +0200 +++ gcc/testsuite/c-c++-common/pr119614-1.c 2025-04-03 22:21:26.201416120 +0200 @@ -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); +} --- gcc/testsuite/c-c++-common/pr119614-2.c.jj 2025-04-03 22:22:12.584779742 +0200 +++ gcc/testsuite/c-c++-common/pr119614-2.c 2025-04-03 22:21:42.035198879 +0200 @@ -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); +} --- gcc/testsuite/c-c++-common/pr119614-3.c.jj 2025-04-03 22:22:17.302715007 +0200 +++ gcc/testsuite/c-c++-common/pr119614-3.c 2025-04-03 22:21:51.423070078 +0200 @@ -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); +} Jakub