]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tailc: Use the IPA-VRP tail call hack even for pointers [PR119614]
authorJakub Jelinek <jakub@redhat.com>
Fri, 4 Apr 2025 06:59:51 +0000 (08:59 +0200)
committerJakub Jelinek <jakub@redhat.com>
Fri, 4 Apr 2025 06:59:51 +0000 (08:59 +0200)
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.

gcc/testsuite/c-c++-common/pr119614-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr119614-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr119614-3.c [new file with mode: 0644]
gcc/tree-tailcall.cc

diff --git a/gcc/testsuite/c-c++-common/pr119614-1.c b/gcc/testsuite/c-c++-common/pr119614-1.c
new file mode 100644 (file)
index 0000000..89105a3
--- /dev/null
@@ -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 (file)
index 0000000..8833eee
--- /dev/null
@@ -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 (file)
index 0000000..59ed36b
--- /dev/null
@@ -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);
+}
index 477729ca2137aeed42ee36c3a103ee941aeb3795..c5fac51522548a6e9ee75e53052db4e9708fba5a 100644 (file)
@@ -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)