On Tue, Nov 5, 2024 at 8:48 AM Jeff Law <jeffreya...@gmail.com> wrote:
>
>
>
> On 11/4/24 5:42 PM, H.J. Lu wrote:
> > On Tue, Nov 5, 2024 at 8:07 AM Jeff Law <jeffreya...@gmail.com> wrote:
> >>
> >>
> >>
> >> On 11/1/24 4:32 PM, H.J. Lu 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 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.
> >> Is there a particular reason x86 can't use the same mechanisms that
> >
> > Other targets define TARGET_PROMOTE_PROTOTYPES to return false
> > to avoid this issue.   Changing x86 TARGET_PROMOTE_PROTOTYPES
> > to return false will break LLVM which assumes that incoming char/short
> > arguments on x86 are always extended to int.   The following targets
> Then my suggestion would be to cover this in REE somehow.  We started
> looking at that a couple years ago and set it aside.   But the basic
> idea was to expose the ABI guarantees to REE, then let REE do its thing.
>
> Jeff
>

For

extern int baz (char c1);

int
foo (char c1)
{
  return baz (c1);
}

on i386, we get these

(insn 7 4 8 2 (set (reg:SI 0 ax [orig:102 c1 ] [102])
        (sign_extend:SI (mem/c:QI (plus:SI (reg/f:SI 7 sp)
                    (const_int 4 [0x4])) [0 c1+0 S1 A32]))) "x.c":6:10
190 {extendqisi2}
     (expr_list:REG_EQUIV (mem:SI (reg/f:SI 16 argp) [0  S4 A32])
        (nil)))
(insn 8 7 9 2 (set (mem:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 4 [0x4])) [0  S4 A32])
        (reg:SI 0 ax [orig:102 c1 ] [102])) "x.c":6:10 95 {*movsi_internal}
     (nil))
(call_insn/j 9 8 10 2 (set (reg:SI 0 ax)
        (call (mem:QI (symbol_ref:SI ("baz") [flags 0x41]
<function_decl 0x7f27347aae00
baz>) [0 baz S1 A8])
            (const_int 4 [0x4]))) "x.c":6:10 1420 {*sibcall_value}
     (expr_list:REG_CALL_DECL (symbol_ref:SI ("baz") [flags 0x41]
<function_decl 0x7f273
47aae00 baz>)
        (nil))
    (expr_list:SI (use (mem:SI (reg/f:SI 16 argp) [0  S4 A32]))
        (nil)))

before REE.  How should REE work to elimate

(insn 7 4 8 2 (set (reg:SI 0 ax [orig:102 c1 ] [102])
        (sign_extend:SI (mem/c:QI (plus:SI (reg/f:SI 7 sp)
                    (const_int 4 [0x4])) [0 c1+0 S1 A32]))) "x.c":6:10
190 {extendqisi2}
     (expr_list:REG_EQUIV (mem:SI (reg/f:SI 16 argp) [0  S4 A32])
        (nil)))
(insn 8 7 9 2 (set (mem:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 4 [0x4])) [0  S4 A32])
        (reg:SI 0 ax [orig:102 c1 ] [102])) "x.c":6:10 95 {*movsi_internal}
     (nil))


-- 
H.J.

Reply via email to