Skip to content
Snippets Groups Projects
Commit ebd111a2 authored by Jakub Jelinek's avatar Jakub Jelinek Committed by Jakub Jelinek
Browse files

icf: Compare call argument types in certain cases and asm operands [PR117432]

compare_operand uses operand_equal_p under the hood, which e.g. for
INTEGER_CSTs will just match the values rather regardless of their types.
Now, in many comparing the type is redundant, if we have
  x_2 = y_3 + 1;
we've already compared the type for the lhs and also for rhs1, there won't
be any surprises on rhs2.
As noted in the PR, there are cases where the type of the operand is the
sole place of information and we don't want to ICF merge functions if the
types differ.
One case is stdarg functions, arguments passed to ..., it is different
if we pass 1, 1L, 1LL.
Another case are the K&R unprototyped functions (sure, gone in C23).
And yet another case are inline asm operands, "r" (1) is different from "r"
(1L) from "r" (1LL).

So, the following patch determines based on lack of fntype (e.g. for
internal functions), or on !prototype_p, or on stdarg_p (in that case
using number of named arguments) which arguments need to have type checked
and does that, plus compares types on inline asm operands (maybe it would be
enough to do that just for input operands but we have just a routine to
handle both and I didn't feel we need to differentiate).

Furthermore, I've noticed fntype{1,2} isn't actually compared if it is a
direct call (gimple_call_fndecl is non-NULL).  That is wrong too, we could
have
  void (*fn) (int, long long) = (void (*) (int, long long)) foo;
  fn (1, 1LL);
in one case and
  void (*fn) (long long, int) = (void (*) (long long, int)) foo;
  fn (1LL, 1);
in another, both folded into a direct call of foo with different
gimple_call_fntype.  Sure, one of them would be UB at runtime (or both), but
what if we ICF merge it into something that into the one UB at runtime
and the program actually calls the correct one only?

2025-02-01  Jakub Jelinek  <jakub@redhat.com>

	PR ipa/117432
	* ipa-icf-gimple.cc (func_checker::compare_asm_inputs_outputs):
	Also return_false if operands have incompatible types.
	(func_checker::compare_gimple_call): Check fntype1 vs. fntype2
	compatibility for all non-internal calls and assume fntype1 and
	fntype2 are non-NULL for those.  For calls to non-prototyped
	calls or for stdarg_p functions after the last named argument (if any)
	check type compatibility of call arguments.

	* gcc.c-torture/execute/pr117432.c: New test.
	* gcc.target/i386/pr117432.c: New test.
parent 6141fd55
No related branches found
No related tags found
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment