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.

Reply via email to