From 728347922a60d5e560a4071d23c492e8baeab115 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 5 Sep 2019 15:30:23 +0200 Subject: [PATCH] re PR middle-end/91001 (internal compiler error: in extract_insn, at recog.c:2310) 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. From-SVN: r275408 --- gcc/ChangeLog | 9 ++++++ gcc/calls.c | 12 ++++--- gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/gcc.c-torture/compile/pr91001.c | 31 +++++++++++++++++++ 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr91001.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1de96224c20..e76ed4adf93 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-09-05 Jakub Jelinek + + 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-05 Richard Biener PR rtl-optimization/91656 diff --git a/gcc/calls.c b/gcc/calls.c index 6eefeec17d9..e5086f4bb1d 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2771,6 +2771,11 @@ 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 ((TREE_CODE (type) == UNION_TYPE + || TREE_CODE (type) == RECORD_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 @@ -2783,11 +2788,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; @@ -2914,8 +2919,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/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1d48a80c580..3a905cb3156 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-09-05 Jakub Jelinek + + PR middle-end/91001 + PR middle-end/91105 + PR middle-end/91106 + * gcc.c-torture/compile/pr91001.c: New test. + 2019-09-05 Richard Biener PR rtl-optimization/91656 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); +} -- 2.30.2