]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end/118174 - bogus TER of tailcall
authorRichard Biener <rguenther@suse.de>
Tue, 31 Dec 2024 13:47:03 +0000 (14:47 +0100)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 1 Jan 2025 14:31:43 +0000 (15:31 +0100)
The following avoids applying TER to direct internal functions that
are tailcall since the involved expansion code path doesn't honor
TER constraints.

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 [new file with mode: 0644]
gcc/tree-outof-ssa.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr118174.c b/gcc/testsuite/gcc.dg/torture/pr118174.c
new file mode 100644 (file)
index 0000000..faacef2
--- /dev/null
@@ -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;
+}
index e51d5e0403aa9c76e4f5254e04004867ffdfd229..cbe572f8681f5a331669f4aba5d5de325a698af1 100644 (file)
@@ -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.  */