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


Reply via email to