From e488c24ec0923d150df9bd41005aa34ce37245ff Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 7 Apr 2015 16:35:18 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 4 ++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/debug/pr65678.C | 35 ++++++++++++++++++++++++++++ gcc/valtrack.c | 31 ++++++++++++++++++------ 4 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/debug/pr65678.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dcb7e99bd7f..d4bf73ad9a7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2015-04-07 Jakub Jelinek + 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 933da2cac14..6d8ce3700e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2015-04-07 Jakub Jelinek + 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 00000000000..d99c73bf1bc --- /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 804b8e880ed..3dfb8a97aea 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; -- 2.30.2