Commit e488c24e by Jakub Jelinek Committed by Jakub Jelinek

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
parent dcc72b9e
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.
......
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.
......
// 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 ();
}
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment