aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-04-04 08:59:51 +0200
committerJakub Jelinek <jakub@redhat.com>2025-04-04 08:59:51 +0200
commit08e803aa9becf407eb7ef7cf6af96e3bd0d02d38 (patch)
tree1fba568ac318cdee49f6cd25ce93f2a329c75a19
parent89b56e903e3a170a8eff2140417cdf81f1d87c9d (diff)
downloadgcc-08e803aa9becf407eb7ef7cf6af96e3bd0d02d38.zip
gcc-08e803aa9becf407eb7ef7cf6af96e3bd0d02d38.tar.gz
gcc-08e803aa9becf407eb7ef7cf6af96e3bd0d02d38.tar.bz2
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 <jakub@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.
-rw-r--r--gcc/testsuite/c-c++-common/pr119614-1.c28
-rw-r--r--gcc/testsuite/c-c++-common/pr119614-2.c28
-rw-r--r--gcc/testsuite/c-c++-common/pr119614-3.c28
-rw-r--r--gcc/tree-tailcall.cc4
4 files changed, 87 insertions, 1 deletions
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 0000000..89105a3
--- /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 0000000..8833eee
--- /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 0000000..59ed36b
--- /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 477729c..c5fac51 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)