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

Jakub Jelinek jakub@redhat.com
Wed Jun 5 08:35:00 GMT 2019


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?

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



More information about the Gcc-patches mailing list