middle-end/118174 - bogus TER of tailcall

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.
This commit is contained in:
Richard Biener 2024-12-31 14:47:03 +01:00 committed by Richard Biener
parent f8cd181e2d
commit f8b5596260
2 changed files with 31 additions and 4 deletions

View file

@ -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;
}

View 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. */