On Fri, Nov 8, 2024 at 5:32 AM H.J. Lu <hjl.to...@gmail.com> wrote: > > On Thu, Nov 7, 2024 at 8:16 PM Richard Biener > <richard.guent...@gmail.com> wrote: > > > > On Thu, Nov 7, 2024 at 5:50 AM H.J. Lu <hjl.to...@gmail.com> wrote: > > > > > > TARGET_PROMOTE_PROTOTYPES isn't defined for psABI purpose. > > > > > x86 psABI doesn't require it. GCC uses only the lower bits of > > > > > incoming > > > > > arguments. But it isn't the GCC's job to promote incoming arguments > > > > > and copy them to outgoing arguments since not usages of such functions > > > > > are compiled by GCC. > > > > > > > > But if you now elide the promotion for the call to foo in > > > > > > > > static void foo (char c) { ... } > > > > > > Only calling local functions, like foo, is an issue. There is no > > > issue if foo is global. Optimization for calling global functions > > > is OK. Am I correct? > > > > I think it's OK to elide the promotion for calls to global functions, > > but as you can't rely on the incoming promotion, this would eventually > > just undo promote_prototypes. > > > > Like when you LTO the Fortran TU I gave with the C implementation the > > Fortran FE will not have applied promote_prototypes to the call of the > > C implementation but the C implementation will have DECL_ARG_TYPE > > in a way to suggest it has. And both functions likely appear to be local > > due to using LTO. > > > > So whether it's safe to elide promote_prototypes depends on whether > > somebody else (in this case combine) would still rely on it being > > performed (I think combine is wrong today, at least when LTO is involved > > and thus it's "all callers visible" argument falls down). > > > > Richard. > > Here is the v2 patch which only optimizes for calling global functions. > > For targets, like x86, which define TARGET_PROMOTE_PROTOTYPES to return > true, all integer arguments smaller than int are passed as int: > > [hjl@gnu-tgl-3 pr14907]$ cat x.c > extern int baz (char c1); > > int > foo (char c1) > { > return baz (c1); > } > [hjl@gnu-tgl-3 pr14907]$ gcc -S -O2 -m32 x.c > [hjl@gnu-tgl-3 pr14907]$ cat x.s > .file "x.c" > .text > .p2align 4 > .globl foo > .type foo, @function > foo: > .LFB0: > .cfi_startproc > movsbl 4(%esp), %eax > movl %eax, 4(%esp) > jmp baz > .cfi_endproc > .LFE0: > .size foo, .-foo > .ident "GCC: (GNU) 14.2.1 20240912 (Red Hat 14.2.1-3)" > .section .note.GNU-stack,"",@progbits > [hjl@gnu-tgl-3 pr14907]$ > > But integer promotion: > > movsbl 4(%esp), %eax > movl %eax, 4(%esp) > > isn't necessary if incoming arguments and outgoing arguments are the > same. Use unpromoted incoming integer arguments as outgoing arguments > if incoming integer arguments are the same as outgoing arguments to > avoid unnecessary integer promotion. > > NB: This optimization only applies to calling external functions since > for > > static void foo (char c) { ... } > void bar (char c) { foo (c); } > > the existing combine optimization assumes that all callers of the local > function, foo, will promote the outgoing char argument to int. Since > we don't control all callers of the global function, bar, we must extend > bar's outgoing char argument to int when calling foo.
So rather than "undoing" the frontends applying promote_prototypes during RTL expansion why not apply (or not apply) promote_prototypes at RTL expansion in the first place? I view promote_prototypes as an optimizing local ABI decision, optimizing because it avoids false dependences on upper halfs of the lo regs(?) Richard. > gcc/ > > PR middle-end/14907 > * calls.cc: Include "ssa.h", "tree-ssa-live.h" and > "tree-outof-ssa.h". > (arg_data): Add unpromoted_int_parm_rtx. > (precompute_register_parameters): Use unpromoted_int_parm_rtx > as argument value if available. > (get_unpromoted_int_parm_rtx_from_ssa_name): New function. > (get_unpromoted_int_parm_rtx): Likewise. > (initialize_argument_information): Add an argument for function > parameter types. Set unpromoted_int_parm_rtx if integer function > arguments of a external function are promoted to int. Change > mode, reg and tail_call_reg to the same mode as > unpromoted_int_parm_rtx. > (expand_call): Pass type_arg_types to > initialize_argument_information. > (store_one_arg): Use unpromoted_int_parm_rtx as argument value > if available. > > gcc/testsuite/ > > PR middle-end/14907 > * gcc.target/i386/pr14907-1.c: New test. > * gcc.target/i386/pr14907-2.c: Likewise. > * gcc.target/i386/pr14907-3.c: Likewise. > * gcc.target/i386/pr14907-4.c: Likewise. > * gcc.target/i386/pr14907-5.c: Likewise. > * gcc.target/i386/pr14907-6.c: Likewise. > * gcc.target/i386/pr14907-7.c: Likewise. > * gcc.target/i386/pr14907-8.c: Likewise. > * gcc.target/i386/pr14907-9.c: Likewise. > * gcc.target/i386/pr14907-10.c: Likewise. > * gcc.target/i386/pr14907-11.c: Likewise. > * gcc.target/i386/pr14907-12.c: Likewise. > * gcc.target/i386/pr14907-13.c: Likewise. > * gcc.target/i386/pr14907-14.c: Likewise. > * gcc.target/i386/pr14907-15.c: Likewise. > > -- > H.J.