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? > 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? > 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 the limitation of implementing this without help of the target? 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.