diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-09-05 15:30:23 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-09-05 15:30:23 +0200 |
commit | 728347922a60d5e560a4071d23c492e8baeab115 (patch) | |
tree | fe8d6c7512fc1b1137aa84003bd9b504d3d69998 /gcc | |
parent | 5a4c9a493153f6f579cd81905d0ab743dd88a33d (diff) | |
download | gcc-728347922a60d5e560a4071d23c492e8baeab115.zip gcc-728347922a60d5e560a4071d23c492e8baeab115.tar.gz gcc-728347922a60d5e560a4071d23c492e8baeab115.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/calls.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr91001.c | 31 |
4 files changed, 55 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1de9622..e76ed4a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +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-05 Richard Biener <rguenther@suse.de> PR rtl-optimization/91656 diff --git a/gcc/calls.c b/gcc/calls.c index 6eefeec..e5086f4 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 1d48a80..3a905cb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +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-05 Richard Biener <rguenther@suse.de> 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 0000000..4b6a017 --- /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); +} |