On Tue, Apr 29, 2025 at 12:32 PM H.J. Lu <hjl.to...@gmail.com> wrote: > > 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.
Is it possible to dissect this from TARGET_PROMOTE_PROTOTYPES then? That is, this should also work for the case prototypes are not promoted and for modes larger than SImode, even BLKmode. Richard. > > > > > > > 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.