aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-04-07 16:35:18 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2015-04-07 16:35:18 +0200
commite488c24ec0923d150df9bd41005aa34ce37245ff (patch)
treec20ea6a4b859dab7e1af67d49463182dcfc7732d
parentdcc72b9e73852d9e3b5f40c6dc51da12c444d699 (diff)
downloadgcc-e488c24ec0923d150df9bd41005aa34ce37245ff.zip
gcc-e488c24ec0923d150df9bd41005aa34ce37245ff.tar.gz
gcc-e488c24ec0923d150df9bd41005aa34ce37245ff.tar.bz2
re PR debug/65678 (internal compiler error: in gen_rtx_SUBREG, at emit-rtl.c:909)
PR debug/65678 * valtrack.c (debug_lowpart_subreg): New function. (dead_debug_insert_temp): Use it. * g++.dg/debug/pr65678.C: New test. From-SVN: r221900
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/debug/pr65678.C35
-rw-r--r--gcc/valtrack.c31
4 files changed, 66 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dcb7e99..d4bf73a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2015-04-07 Jakub Jelinek <jakub@redhat.com>
+ PR debug/65678
+ * valtrack.c (debug_lowpart_subreg): New function.
+ (dead_debug_insert_temp): Use it.
+
PR middle-end/65680
* expr.c (get_inner_reference): Handle bit_offset that doesn't fit
into signed HOST_WIDE_INT the same as negative bit_offset.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 933da2c..6d8ce37 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2015-04-07 Jakub Jelinek <jakub@redhat.com>
+ PR debug/65678
+ * g++.dg/debug/pr65678.C: New test.
+
PR middle-end/65680
* gcc.c-torture/compile/pr65680.c: New test.
diff --git a/gcc/testsuite/g++.dg/debug/pr65678.C b/gcc/testsuite/g++.dg/debug/pr65678.C
new file mode 100644
index 0000000..d99c73b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/pr65678.C
@@ -0,0 +1,35 @@
+// PR debug/65678
+// { dg-do compile }
+
+long long v;
+
+static int
+bar (double x)
+{
+#if __SIZEOF_DOUBLE__ == __SIZEOF_LONG_LONG__
+ __builtin_memmove (&v, &x, sizeof v);
+#else
+ (void) x;
+ v = 0;
+#endif
+ return v;
+}
+
+struct A
+{
+ A (double x) : a (bar (x)) {}
+ int m1 ();
+ int m2 () { int b = a; return b; }
+ int a;
+};
+
+void foo ();
+
+void
+baz (double x)
+{
+ int c = A (x).m2 ();
+ int d = A (x).m1 ();
+ if (d)
+ foo ();
+}
diff --git a/gcc/valtrack.c b/gcc/valtrack.c
index 804b8e8..3dfb8a9 100644
--- a/gcc/valtrack.c
+++ b/gcc/valtrack.c
@@ -534,6 +534,22 @@ dead_debug_add (struct dead_debug_local *debug, df_ref use, unsigned int uregno)
bitmap_set_bit (debug->used, uregno);
}
+/* Like lowpart_subreg, but if a subreg is not valid for machine, force
+ it anyway - for use in debug insns. */
+
+static rtx
+debug_lowpart_subreg (machine_mode outer_mode, rtx expr,
+ machine_mode inner_mode)
+{
+ if (inner_mode == VOIDmode)
+ inner_mode = GET_MODE (expr);
+ int offset = subreg_lowpart_offset (outer_mode, inner_mode);
+ rtx ret = simplify_gen_subreg (outer_mode, expr, inner_mode, offset);
+ if (ret)
+ return ret;
+ return gen_rtx_raw_SUBREG (outer_mode, expr, offset);
+}
+
/* If UREGNO is referenced by any entry in DEBUG, emit a debug insn
before or after INSN (depending on WHERE), that binds a (possibly
global) debug temp to the widest-mode use of UREGNO, if WHERE is
@@ -662,9 +678,9 @@ dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
/* Ok, it's the same (hardware) REG, but with a different
mode, so SUBREG it. */
else
- breg = lowpart_subreg (GET_MODE (reg),
- cleanup_auto_inc_dec (src, VOIDmode),
- GET_MODE (dest));
+ breg = debug_lowpart_subreg (GET_MODE (reg),
+ cleanup_auto_inc_dec (src, VOIDmode),
+ GET_MODE (dest));
}
else if (GET_CODE (dest) == SUBREG)
{
@@ -684,9 +700,9 @@ dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
breg = NULL;
/* Yay, we can use SRC, just adjust its mode. */
else
- breg = lowpart_subreg (GET_MODE (reg),
- cleanup_auto_inc_dec (src, VOIDmode),
- GET_MODE (dest));
+ breg = debug_lowpart_subreg (GET_MODE (reg),
+ cleanup_auto_inc_dec (src, VOIDmode),
+ GET_MODE (dest));
}
/* Oh well, we're out of luck. */
else
@@ -740,7 +756,8 @@ dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
*DF_REF_REAL_LOC (cur->use) = dval;
else
*DF_REF_REAL_LOC (cur->use)
- = gen_lowpart_SUBREG (GET_MODE (*DF_REF_REAL_LOC (cur->use)), dval);
+ = debug_lowpart_subreg (GET_MODE (*DF_REF_REAL_LOC (cur->use)), dval,
+ GET_MODE (dval));
/* ??? Should we simplify subreg of subreg? */
bitmap_set_bit (debug->to_rescan, INSN_UID (DF_REF_INSN (cur->use)));
uses = cur->next;