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  <ja...@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 <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 247165 (AG München)

Reply via email to