This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix ICE with TYPE_TRANSPARENT_AGGR (PR middle-end/91001)


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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]