On 4/4/25 00:57, Jakub Jelinek wrote:
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?
Are you checking whether we can calculate a range? value_range has a static function for any type it currently supports:
if (value_range::supports_type_p (type)) Currently implemented as inline bool value_range::supports_type_p (const_tree type) { return irange::supports_p (type) || prange::supports_p (type) || frange::supports_p (type); }
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