On Fri, Nov 8, 2024 at 5:32 AM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> On Thu, Nov 7, 2024 at 8:16 PM Richard Biener
> <richard.guent...@gmail.com> wrote:
> >
> > On Thu, Nov 7, 2024 at 5:50 AM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> > > > > TARGET_PROMOTE_PROTOTYPES isn't defined for psABI purpose.
> > > > > x86 psABI doesn't require it.   GCC uses only the lower bits of 
> > > > > incoming
> > > > > arguments.   But it isn't the GCC's job to promote incoming arguments
> > > > > and copy them to outgoing arguments since not usages of such functions
> > > > > are compiled by GCC.
> > > >
> > > > But if you now elide the promotion for the call to foo in
> > > >
> > > > static void foo (char c) { ... }
> > >
> > > Only calling local functions, like foo, is an issue.  There is no
> > > issue if foo is global.   Optimization for calling global functions
> > > is OK.  Am I correct?
> >
> > I think it's OK to elide the promotion for calls to global functions,
> > but as you can't rely on the incoming promotion, this would eventually
> > just undo promote_prototypes.
> >
> > Like when you LTO the Fortran TU I gave with the C implementation the
> > Fortran FE will not have applied promote_prototypes to the call of the
> > C implementation but the C implementation will have DECL_ARG_TYPE
> > in a way to suggest it has.  And both functions likely appear to be local
> > due to using LTO.
> >
> > So whether it's safe to elide promote_prototypes depends on whether
> > somebody else (in this case combine) would still rely on it being
> > performed (I think combine is wrong today, at least when LTO is involved
> > and thus it's "all callers visible" argument falls down).
> >
> > Richard.
>
> Here is the v2 patch which only optimizes for calling global functions.
>
> 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 and outgoing arguments are the
> same.  Use unpromoted incoming integer arguments as outgoing arguments
> if incoming integer arguments are the same as outgoing arguments to
> avoid unnecessary integer promotion.
>
> NB: This optimization only applies to calling external functions since
> for
>
> static void foo (char c) { ... }
> void bar (char c) { foo (c); }
>
> the existing combine optimization assumes that all callers of the local
> function, foo, will promote the outgoing char argument to int.  Since
> we don't control all callers of the global function, bar, we must extend
> bar's outgoing char argument to int when calling foo.

So rather than "undoing" the frontends applying promote_prototypes
during RTL expansion why not apply (or not apply) promote_prototypes
at RTL expansion in the first place?  I view promote_prototypes as
an optimizing local ABI decision, optimizing because it avoids false
dependences on upper halfs of the lo regs(?)

Richard.

> gcc/
>
> PR middle-end/14907
> * calls.cc: Include "ssa.h", "tree-ssa-live.h" and
> "tree-outof-ssa.h".
> (arg_data): Add unpromoted_int_parm_rtx.
> (precompute_register_parameters): Use unpromoted_int_parm_rtx
> as argument value if available.
> (get_unpromoted_int_parm_rtx_from_ssa_name): New function.
> (get_unpromoted_int_parm_rtx): Likewise.
> (initialize_argument_information): Add an argument for function
> parameter types.  Set unpromoted_int_parm_rtx if integer function
> arguments of a external function are promoted to int.  Change
> mode, reg and tail_call_reg to the same mode as
> unpromoted_int_parm_rtx.
> (expand_call): Pass type_arg_types to
> initialize_argument_information.
> (store_one_arg): Use unpromoted_int_parm_rtx as argument value
> if available.
>
> 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-7.c: Likewise.
> * gcc.target/i386/pr14907-8.c: Likewise.
> * gcc.target/i386/pr14907-9.c: Likewise.
> * gcc.target/i386/pr14907-10.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.
>
> --
> H.J.

Reply via email to