On Tue, Apr 29, 2025 at 5:56 PM Richard Biener <richard.guent...@gmail.com> wrote: > > On Tue, Apr 29, 2025 at 10:48 AM H.J. Lu <hjl.to...@gmail.com> wrote: > > > > On Tue, Apr 29, 2025 at 4:25 PM Richard Biener > > <richard.guent...@gmail.com> wrote: > > > > > > On Tue, Apr 29, 2025 at 9:39 AM H.J. Lu <hjl.to...@gmail.com> wrote: > > > > > > > > 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 are copied to outgoing arguments > > > > directly. > > > > > > > > Add a new target hook, TARGET_GET_SMALL_INTEGER_ARGUMENT_VALUE, > > > > defaulting > > > > to return nullptr. If the new target hook returns non-nullptr, use it > > > > to > > > > get the outgoing small integer argument. The x86 target hook returns > > > > the > > > > value of the corresponding incoming argument as int if it can be used as > > > > the outgoing argument. If callee is a global function, we always > > > > properly > > > > extend the incoming small integer arguments in callee. If callee is a > > > > local function, since DECL_ARG_TYPE has the original small integer type, > > > > we will extend the incoming small integer arguments in callee if needed. > > > > It is safe only if > > > > > > > > 1. Caller and callee are not nested functions. > > > > 2. Caller and callee use the same ABI. > > > > > > How do these influence the value? TARGET_PROMOTE_PROTOTYPES > > > should apply to all of them, no? > > > > When the arguments are passed in different registers in different ABIs, > > we have to copy them anyway. > > But optimization can elide copies easily, but not easily elide > sign-/zero-extensions.
What I meant was that caller and callee have different ABIs. Optimizer can't elide copies since incoming arguments and outgoing arguments are in different registers. They have to be moved. > > > > > > > 3. The incoming argument and the outgoing argument are in the same > > > > location. > > > > > > Why's that? Can't we move them but still elide the sign-/zero-extension? > > > > If they aren't in the same locations, we have to move them anyway. > > This patch tries to avoid necessary moves of incoming arguments to > > outgoing arguments. > > That's not exactly how you presented it, but you convenitently used > x86 stack argument passing. That might be difficult to elide, but is > also uncommon for "small integer types" - does the same issue not > apply to other arguments passed on the stack as well? It applies to both passing in registers and on stack. It is an issue only for small integer types due to sign-/zero-extensions at call sites. My patch elides sign-/zero-extensions when incoming arguments and outgoing arguments are unchanged in the exactly same location, in register or on stack. > > > > > 4. The incoming argument is unchanged before call expansion. > > > > > > Obviously, but then IMO this reveals an issue with the design of a target > > > hook > > > returning the argument register - it returns a place rather than a > > > value. Wha'ts > > > > We need the place so that we can avoid meaningless copy. > > > > > the limitation of implementing this without help of the target? > > > > Middle-end may not know what is safe and not safe, for example, we > > can skip the hidden argument SUBREG for x32. > > > > > Richard. > > > > > > > Otherwise, using the incoming argument as the outgoing argument may > > > > change > > > > values of other incoming arguments or the wrong outgoing argument value > > > > may be used. > > > > > > > > gcc/ > > > > > > > > PR middle-end/14907 > > > > * calls.cc (arg_data): Add small_integer_argument_value. > > > > (precompute_register_parameters): Set args[i].value to > > > > args[i].small_integer_argument_value if not nullptr. > > > > (initialize_argument_information): Set > > > > args[i].small_integer_argument_value to > > > > TARGET_GET_SMALL_INTEGER_ARGUMENT_VALUE. > > > > (store_one_arg): Set arg->value to arg->small_integer_argument_value > > > > if not nullptr. > > > > * target.def (get_small_integer_argument_value): New for calls. > > > > * targhooks.cc (default_get_small_integer_argument_value): New. > > > > * targhooks.h (default_get_small_integer_argument_value): Likewise. > > > > * config/i386/i386.cc (ix86_get_small_integer_argument_value): New. > > > > (TARGET_GET_SMALL_INTEGER_ARGUMENT_VALUE): Likewise. > > > > * config/i386/i386.h (machine_function): Add > > > > no_small_integer_argument_value and before_first_expand_call. > > > > * doc/tm.texi: Regenerated. > > > > * doc/tm.texi.in (TARGET_GET_SMALL_INTEGER_ARGUMENT_VALUE): New > > > > hook. > > > > > > > > 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-7a.c: Likewise. > > > > * gcc.target/i386/pr14907-7b.c: Likewise. > > > > * gcc.target/i386/pr14907-8a.c: Likewise. > > > > * gcc.target/i386/pr14907-8b.c: Likewise. > > > > * gcc.target/i386/pr14907-9a.c: Likewise. > > > > * gcc.target/i386/pr14907-9b.c: Likewise. > > > > * gcc.target/i386/pr14907-10a.c: Likewise. > > > > * gcc.target/i386/pr14907-10b.c: Likewise. > > > > * gcc.target/i386/pr14907-10c.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. > > > > * gcc.target/i386/pr14907-16.c: Likewise. > > > > * gcc.target/i386/pr14907-17.c: Likewise. > > > > * gcc.target/i386/pr14907-18a.c: Likewise. > > > > * gcc.target/i386/pr14907-18b.c: Likewise. > > > > * gcc.target/i386/pr14907-19.c: Likewise. > > > > * gcc.target/i386/pr14907-20a.c: Likewise. > > > > * gcc.target/i386/pr14907-20b.c: Likewise. > > > > * gcc.target/i386/pr14907-21.c: Likewise. > > > > * gcc.target/i386/pr14907-22.c: Likewise. > > > > > > > > > > > > -- > > > > H.J. > > > > > > > > -- > > H.J. -- H.J.