On Wed, Dec 4, 2024 at 9:48 PM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> Promote integer arguments smaller than int if TARGET_PROMOTE_PROTOTYPES
> returns true.

This is OK when 2/7 got no negative comments and Jeff doesn't have
further input here.

(I think 1/7+2/7 are a good improvement on their own given the latent bugfixing)

Also CCed Eric who might also know calls.c quite well.

Richard.

>         PR middle-end/112877
>         * calls.c (initialize_argument_information): Promote small integer
>         arguments if TARGET_PROMOTE_PROTOTYPES returns true.
>
> gcc/testsuite/
>
>         PR middle-end/112877
>         * gfortran.dg/pr112877-1.f90: New test.
>
> Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
> ---
>  gcc/calls.cc                             |  9 +++++++++
>  gcc/testsuite/gfortran.dg/pr112877-1.f90 | 17 +++++++++++++++++
>  2 files changed, 26 insertions(+)
>  create mode 100644 gcc/testsuite/gfortran.dg/pr112877-1.f90
>
> diff --git a/gcc/calls.cc b/gcc/calls.cc
> index 8cf0f29b42c..78ead6fd4ed 100644
> --- a/gcc/calls.cc
> +++ b/gcc/calls.cc
> @@ -1374,6 +1374,11 @@ initialize_argument_information (int num_actuals 
> ATTRIBUTE_UNUSED,
>        }
>    }
>
> +  bool promote_p
> +    = targetm.calls.promote_prototypes (fndecl
> +                                       ? TREE_TYPE (fndecl)
> +                                       : fntype);
> +
>    /* I counts args in order (to be) pushed; ARGPOS counts in order written.  
> */
>    for (argpos = 0; argpos < num_actuals; i--, argpos++)
>      {
> @@ -1383,6 +1388,10 @@ initialize_argument_information (int num_actuals 
> ATTRIBUTE_UNUSED,
>        /* Replace erroneous argument with constant zero.  */
>        if (type == error_mark_node || !COMPLETE_TYPE_P (type))
>         args[i].tree_value = integer_zero_node, type = integer_type_node;
> +      else if (promote_p
> +              && INTEGRAL_TYPE_P (type)
> +              && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
> +       type = integer_type_node;
>
>        /* If TYPE is a transparent union or record, pass things the way
>          we would pass the first field of the union or record.  We have
> diff --git a/gcc/testsuite/gfortran.dg/pr112877-1.f90 
> b/gcc/testsuite/gfortran.dg/pr112877-1.f90
> new file mode 100644
> index 00000000000..f5596f0d0ad
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/pr112877-1.f90
> @@ -0,0 +1,17 @@
> +! { dg-do compile }
> +! { dg-options "-Os" }
> +
> +program test
> +    use iso_c_binding, only: c_short
> +    interface
> +      subroutine foo(a) bind(c)
> +        import c_short
> +        integer(kind=c_short), intent(in), value :: a
> +      end subroutine foo
> +    end interface
> +    integer(kind=c_short) a(5);
> +    call foo (a(3))
> +end
> +
> +! { dg-final { scan-assembler "movswl\t10\\(%rsp\\), %edi" { target { { 
> i?86-*-linux* i?86-*-gnu* x86_64-*-linux* x86_64-*-gnu* } && { ! ia32 } } } } 
> }
> +! { dg-final { scan-assembler "movswl\t-14\\(%ebp\\), %eax" { target { { 
> i?86-*-linux* i?86-*-gnu* x86_64-*-linux* x86_64-*-gnu* } && { ia32 } } } } }
> --
> 2.47.1
>

Reply via email to