The following avoids applying TER to direct internal functions that
are tailcall since the involved expansion code path doesn't honor
TER constraints.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

        PR middle-end/118174
        * tree-outof-ssa.cc (ssa_is_replaceable_p): Exclude tailcalls.

        * gcc.dg/torture/pr118174.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr118174.c | 24 ++++++++++++++++++++++++
 gcc/tree-outof-ssa.cc                   | 11 +++++++----
 2 files changed, 31 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr118174.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr118174.c 
b/gcc/testsuite/gcc.dg/torture/pr118174.c
new file mode 100644
index 00000000000..faacef24c8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr118174.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+
+int __attribute__((noipa))
+foo (signed char *p1, signed char *p2)
+{
+  int sum = 0;
+  for (int i = 0; i < 32; i++)
+    sum += __builtin_abs (p1[i] - p2[i]);
+  return sum;
+}
+
+int
+main()
+{
+  signed char a[32], b[32];
+  for (int i = 0; i < 32; ++i)
+    {
+      a[i] = i;
+      b[i] = 16 - i;
+    }
+  if (foo (a, b) != 624)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-outof-ssa.cc b/gcc/tree-outof-ssa.cc
index e51d5e0403a..cbe572f8681 100644
--- a/gcc/tree-outof-ssa.cc
+++ b/gcc/tree-outof-ssa.cc
@@ -61,11 +61,14 @@ ssa_is_replaceable_p (gimple *stmt)
   tree def;
   gimple *use_stmt;
 
-  /* Only consider modify stmts and direct internal fn calls.  */
+  /* Only consider modify stmts and direct internal fn calls that are
+     not also tail-calls.  */
+  gcall *call;
   if (!is_gimple_assign (stmt)
-      && (!is_gimple_call (stmt)
-         || !gimple_call_internal_p (stmt)
-         || !direct_internal_fn_p (gimple_call_internal_fn (stmt))))
+      && (!(call = dyn_cast <gcall *> (stmt))
+         || gimple_call_tail_p (call)
+         || !gimple_call_internal_p (call)
+         || !direct_internal_fn_p (gimple_call_internal_fn (call))))
     return false;
 
   /* If the statement may throw an exception, it cannot be replaced.  */
-- 
2.43.0

Reply via email to