https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117432

--- Comment #20 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-13 branch has been updated by Jakub Jelinek
<ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:b4b559ab9dc35dc80fc05f840a63381defd2f7a5

commit r13-9587-gb4b559ab9dc35dc80fc05f840a63381defd2f7a5
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Sat Feb 1 00:50:24 2025 +0100

    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  <ja...@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.

    (cherry picked from commit ebd111a2896816e4f5ddf5108f361b3d9d287fa0)

Reply via email to