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 <ja...@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 <rguent...@suse.de> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg)