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.

Reply via email to