This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix ICE with TYPE_TRANSPARENT_AGGR (PR middle-end/91001)
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Eric Botcazou <ebotcazou at adacore dot com>, Jeff Law <law at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Thu, 5 Sep 2019 15:26:52 +0200 (CEST)
- Subject: Re: [PATCH] Fix ICE with TYPE_TRANSPARENT_AGGR (PR middle-end/91001)
- References: <20190905091228.GB2120@tucnak>
On Thu, 5 Sep 2019, Jakub Jelinek wrote:
> Hi!
>
> The following testcase ICEs on most targets. The problem is that
> initialize_argument_information properly considers the type of the first
> field in this case for how the aggregate should be passed, but then
> load_register_parameters uses the type of the aggregate unmodified in
> the computation of e.g. how many registers to use. So, if as in the
> testcase the first field needs at most one word, but the whole union
> needs say 16 words, we use 15 hard registers after the one chosen,
> which can include say special flags register, frame, floating point regs,
> whatever, including running into virtual registers or pseudo registers.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
OK.
Thanks,
Richard.
> 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.
>
> --- gcc/calls.c.jj 2019-08-27 12:27:06.000000000 +0200
> +++ gcc/calls.c 2019-09-04 13:34:10.764020515 +0200
> @@ -2771,6 +2771,11 @@ load_register_parameters (struct arg_dat
> 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_dat
> 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_dat
> 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);
> }
> --- gcc/testsuite/gcc.c-torture/compile/pr91001.c.jj 2019-09-04 13:48:25.428062724 +0200
> +++ gcc/testsuite/gcc.c-torture/compile/pr91001.c 2019-09-04 13:47:55.849511169 +0200
> @@ -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);
> +}
>
> Jakub
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 247165 (AG München)