aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-10-21 11:39:53 +0000
committerJakub Jelinek <jakub@redhat.com>2019-10-21 11:39:53 +0000
commitd62e32a46059903f72e4dc7ab4220f62c6b94a03 (patch)
treea21246440279575e591f8c2e8d11b30ad5e9e66a
parentdacabd6b1c7d0165dbbfbfcd7e3221a60422b9a3 (diff)
Backported from mainline
2019-09-06 Jakub Jelinek <jakub@redhat.com> * function.c (assign_parm_find_data_types): Use RECORD_OR_UNION_TYPE_P before testing TYPE_TRANSPARENT_AGGR. * calls.c (initialize_argument_information, load_register_parameters): Likewise. 2019-09-05 Jakub Jelinek <jakub@redhat.com> PR middle-end/91001 PR middle-end/91105 PR middle-end/91106 * calls.c (load_register_parameters): For TYPE_TRANSPARENT_AGGR types, use type of their first field instead of type of args[i].tree_value. * gcc.c-torture/compile/pr91001.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-9-branch@277248 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/calls.c13
-rw-r--r--gcc/function.c3
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr91001.c31
5 files changed, 62 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 64d4e31be0e..0f40e8efb6d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,22 @@
2019-10-21 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2019-09-06 Jakub Jelinek <jakub@redhat.com>
+
+ * function.c (assign_parm_find_data_types): Use RECORD_OR_UNION_TYPE_P
+ before testing TYPE_TRANSPARENT_AGGR.
+ * calls.c (initialize_argument_information, load_register_parameters):
+ Likewise.
+
+ 2019-09-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91001
+ PR middle-end/91105
+ PR middle-end/91106
+ * calls.c (load_register_parameters): For TYPE_TRANSPARENT_AGGR
+ types, use type of their first field instead of type of
+ args[i].tree_value.
+
2019-09-02 Jakub Jelinek <jakub@redhat.com>
PR go/91617
diff --git a/gcc/calls.c b/gcc/calls.c
index c8a42680041..56795995650 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1971,8 +1971,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
/* 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
already verified that the modes are the same. */
- if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
- && TYPE_TRANSPARENT_AGGR (type))
+ if (RECORD_OR_UNION_TYPE_P (type) && TYPE_TRANSPARENT_AGGR (type))
type = TREE_TYPE (first_field (type));
/* Decide where to pass this arg.
@@ -2750,6 +2749,9 @@ load_register_parameters (struct arg_data *args, int num_actuals,
poly_int64 size = 0;
HOST_WIDE_INT const_size = 0;
rtx_insn *before_arg = get_last_insn ();
+ tree type = TREE_TYPE (args[i].tree_value);
+ if (RECORD_OR_UNION_TYPE_P (type) && TYPE_TRANSPARENT_AGGR (type))
+ type = TREE_TYPE (first_field (type));
/* Set non-negative if we must move a word at a time, even if
just one word (e.g, partial == 4 && mode == DFmode). Set
to -1 if we just use a normal move insn. This value can be
@@ -2762,11 +2764,11 @@ load_register_parameters (struct arg_data *args, int num_actuals,
gcc_assert (partial % UNITS_PER_WORD == 0);
nregs = partial / UNITS_PER_WORD;
}
- else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode)
+ else if (TYPE_MODE (type) == BLKmode)
{
/* Variable-sized parameters should be described by a
PARALLEL instead. */
- const_size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+ const_size = int_size_in_bytes (type);
gcc_assert (const_size >= 0);
nregs = (const_size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
size = const_size;
@@ -2893,8 +2895,7 @@ load_register_parameters (struct arg_data *args, int num_actuals,
if (GET_CODE (reg) == PARALLEL)
use_group_regs (call_fusage, reg);
else if (nregs == -1)
- use_reg_mode (call_fusage, reg,
- TYPE_MODE (TREE_TYPE (args[i].tree_value)));
+ use_reg_mode (call_fusage, reg, TYPE_MODE (type));
else if (nregs > 0)
use_regs (call_fusage, REGNO (reg), nregs);
}
diff --git a/gcc/function.c b/gcc/function.c
index c6e862b3369..6c1d27f8a92 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2449,8 +2449,7 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
/* If the parm is to be passed as a transparent union or record, use the
type of the first field for the tests below. We have already verified
that the modes are the same. */
- if ((TREE_CODE (passed_type) == UNION_TYPE
- || TREE_CODE (passed_type) == RECORD_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (passed_type)
&& TYPE_TRANSPARENT_AGGR (passed_type))
passed_type = TREE_TYPE (first_field (passed_type));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e2a268fafaf..1963746212e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,13 @@
2019-10-21 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2019-09-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91001
+ PR middle-end/91105
+ PR middle-end/91106
+ * gcc.c-torture/compile/pr91001.c: New test.
+
2019-09-02 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/91632
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr91001.c b/gcc/testsuite/gcc.c-torture/compile/pr91001.c
new file mode 100644
index 00000000000..4b6a017c860
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr91001.c
@@ -0,0 +1,31 @@
+/* PR middle-end/91001 */
+/* PR middle-end/91105 */
+/* PR middle-end/91106 */
+
+struct __attribute__((packed)) S { short b; char c; };
+struct T { short b, c, d; };
+struct __attribute__((packed)) R { int b; char c; };
+union __attribute__((aligned(128), transparent_union)) U { struct S c; } u;
+union __attribute__((aligned(32), transparent_union)) V { struct T c; } v;
+union __attribute__((aligned(32), transparent_union)) W { struct R c; } w;
+void foo (union U);
+void bar (union V);
+void baz (union W);
+
+void
+qux (void)
+{
+ foo (u);
+}
+
+void
+quux (void)
+{
+ bar (v);
+}
+
+void
+corge (void)
+{
+ baz (w);
+}