aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2024-11-21 08:11:06 +0800
committerH.J. Lu <hjl.tools@gmail.com>2025-04-27 10:36:49 +0800
commit78db4753c9646a372512e6a951fced12f74de0bc (patch)
treed245e0d623189607c4310465ce20e01b25a3b313 /gcc
parentab22b8c630769330b4f37eb64d2bc285344a647a (diff)
downloadgcc-78db4753c9646a372512e6a951fced12f74de0bc.zip
gcc-78db4753c9646a372512e6a951fced12f74de0bc.tar.gz
gcc-78db4753c9646a372512e6a951fced12f74de0bc.tar.bz2
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.tools@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/calls.cc9
-rw-r--r--gcc/testsuite/gfortran.dg/pr112877-1.f9017
2 files changed, 26 insertions, 0 deletions
diff --git a/gcc/calls.cc b/gcc/calls.cc
index 076e046..676f0f9 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 0000000..f5596f0
--- /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 } } } } }