https://gcc.gnu.org/g:78db4753c9646a372512e6a951fced12f74de0bc

commit r16-169-g78db4753c9646a372512e6a951fced12f74de0bc
Author: H.J. Lu <hjl.to...@gmail.com>
Date:   Thu Nov 21 08:11:06 2024 +0800

    Honor TARGET_PROMOTE_PROTOTYPES during RTL expand
    
    Promote integer arguments smaller than int if TARGET_PROMOTE_PROTOTYPES
    returns true.
    
    gcc/
    
            PR middle-end/112877
            * calls.cc (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>

Diff:
---
 gcc/calls.cc                             |  9 +++++++++
 gcc/testsuite/gfortran.dg/pr112877-1.f90 | 17 +++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/gcc/calls.cc b/gcc/calls.cc
index 076e046a8ef1..676f0f9229e0 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -1382,6 +1382,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++)
     {
@@ -1391,6 +1396,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 000000000000..f5596f0d0adc
--- /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 } } } } }

Reply via email to