[PATCH] Fix var-tracking ICE with complex subregs (PR debug/90733)

Richard Biener rguenther@suse.de
Wed Jun 5 09:24:00 GMT 2019


On Wed, 5 Jun 2019, Jakub Jelinek wrote:

> Hi!
> 
> On the following testcase, we have:
> (debug_insn 45 20 22 2 (var_location:DI D#4 (const_int 0 [0])) -1 (nil))
> (debug_insn 22 45 26 2 (debug_marker) "pr90733.c":16:3 -1 (nil))
> (debug_insn 26 22 27 2 (var_location:CSI D#3 (subreg:CSI (debug_expr:DI D#4) 0)) "pr90733.c":16:10 -1 (nil))
> (debug_insn 27 26 28 2 (var_location:SI D#2 (subreg:SI (debug_expr:CSI D#3) 0)) -1 (nil))
> (debug_insn 28 27 29 2 (var_location:SI D#1 (clobber (const_int 0 [0]))) -1 (nil))
> (debug_insn 29 28 30 2 (var_location:CSI y$c (concat:CSI (debug_expr:SI D#2) (debug_expr:SI D#1))) -1 (nil))
> During var-tracking, we first propagate D#4 into the D#3 definition and want
> to simplify_subreg (CSImode, const0_rtx, DImode, 0), unfortunately that
> fails due to simplify_immed_subreg having:
>   /* We have no way to represent a complex constant at the rtl level.  */
>   if (COMPLEX_MODE_P (outermode))
>     return NULL_RTX;
> and later on the following vt_expand_loc_callback hunk forces the creation
> of SUBREG, as in debug insns/notes we generally can handle even invalid
> SUBREGs.  We can't handle SUBREGs where the inner mode is VOIDmode though,
> we don't really know what to do that.  On this testcase, after creating
> such a subreg we simplify another subreg, the SImode lowpart subreg of that
> and that is where we ICE, because subreg of a subreg is invalid, we try
> harder to simplify it and don't know what to do with the VOIDmode in there.
> 
> The following patch fixes the ICE by refusing to create raw SUBREGs with
> VOIDmode inner mode.  Bootstrapped/regtested on x86_64-linux and i686-linux,
> ok for trunk?

OK.

Richard.

> Incrementally, we could into vt_expand_loc_callback add some special case
> for complex modes, if simplify_subreg fails, for complex mode try to
> simplify a lowpart and highpart subregs for the scalar halves and if both
> succeed, create a CONCAT of those, which is what we use in debug insns (as
> debug_insn 29 above shows).  Another option might be to use CONST_VECTORs
> even with complex modes, but I guess that would be a far bigger change.
> 
> 2019-06-05  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR debug/90733
> 	* var-tracking.c (vt_expand_loc_callback): Don't create raw subregs
> 	with VOIDmode inner operands.
> 
> 	* gcc.dg/pr90733.c: New test.
> 
> --- gcc/var-tracking.c.jj	2019-05-03 15:22:07.000000000 +0200
> +++ gcc/var-tracking.c	2019-06-04 16:32:35.014561614 +0200
> @@ -8491,7 +8491,7 @@ vt_expand_loc_callback (rtx x, bitmap re
>  
>        /* Invalid SUBREGs are ok in debug info.  ??? We could try
>  	 alternate expansions for the VALUE as well.  */
> -      if (!result)
> +      if (!result && GET_MODE (subreg) != VOIDmode)
>  	result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
>  
>        return result;
> --- gcc/testsuite/gcc.dg/pr90733.c.jj	2019-06-04 16:43:21.749638839 +0200
> +++ gcc/testsuite/gcc.dg/pr90733.c	2019-06-04 16:42:53.181083748 +0200
> @@ -0,0 +1,22 @@
> +/* PR debug/90733 */
> +/* { dg-do compile } */
> +/* { dg-options "-g -O2 -w" } */
> +
> +struct S { unsigned a : 1; };
> +union U { struct S b; _Complex unsigned c; };
> +
> +union U
> +foo (union U d)
> +{
> +  union U e = d;
> +  return e;
> +}
> +
> +int
> +bar (void)
> +{
> +  union U x, y;
> +  x.c = x.b.a;
> +  y = foo (x);
> +  return x.c != y.c;
> +}
> 
> 	Jakub
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG NÌrnberg)


More information about the Gcc-patches mailing list