diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-04-07 16:35:18 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-04-07 16:35:18 +0200 |
commit | e488c24ec0923d150df9bd41005aa34ce37245ff (patch) | |
tree | c20ea6a4b859dab7e1af67d49463182dcfc7732d /gcc/valtrack.c | |
parent | dcc72b9e73852d9e3b5f40c6dc51da12c444d699 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc/valtrack.c')
-rw-r--r-- | gcc/valtrack.c | 31 |
1 files changed, 24 insertions, 7 deletions
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; |