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