diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2015-06-30 17:40:55 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2015-06-30 17:40:55 +0000 |
commit | ef87312ec1246b8667da99e34ecfacff595c9c21 (patch) | |
tree | 84122957f4d1831b0346a506e4c3aa47b486b0d8 /gcc/lra.c | |
parent | 8b970b6e69aeddad690f7b1465d8aeeeb07c7536 (diff) | |
download | gcc-ef87312ec1246b8667da99e34ecfacff595c9c21.zip gcc-ef87312ec1246b8667da99e34ecfacff595c9c21.tar.gz gcc-ef87312ec1246b8667da99e34ecfacff595c9c21.tar.bz2 |
re PR debug/66691 (ICE on valid code at -O3 with -g enabled in simplify_subreg, at simplify-rtx.c:5744)
2015-06-30 Vladimir Makarov <vmakarov@redhat.com>
PR debug/66691
* lra-int.h (lra_substitute_pseudo): Add a parameter.
(lra_substitute_pseudo_within_insn): Ditto.
* lra.c (lra_substitute_pseudo): Add a parameter. Simplify subreg
of constant.
(lra_substitute_pseudo_within_insn): Add a parameter. Transfer it
to lra_substitute_pseudo.
* lra-lives.c (process_bb_lives): Add an argument to
lra_substitute_pseudo_within_insn call.
* lra-constraints.c (inherit_reload_reg, split_reg): Add an
argument to lra_substitute_pseudo and
lra_substitute_pseudo_within_insn calls.
(remove_inheritance_pseudos, undo_optional_reloads): Ditto.
2015-06-30 Vladimir Makarov <vmakarov@redhat.com>
PR debug/66691
* gcc.target/i386/pr66691.c: New.
From-SVN: r225200
Diffstat (limited to 'gcc/lra.c')
-rw-r--r-- | gcc/lra.c | 41 |
1 files changed, 31 insertions, 10 deletions
@@ -1777,9 +1777,10 @@ lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after, /* Replace all references to register OLD_REGNO in *LOC with pseudo - register NEW_REG. Return true if any change was made. */ + register NEW_REG. Try to simplify subreg of constant if SUBREG_P. + Return true if any change was made. */ bool -lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg) +lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p) { rtx x = *loc; bool result = false; @@ -1791,9 +1792,25 @@ lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg) return false; code = GET_CODE (x); - if (code == REG && (int) REGNO (x) == old_regno) + if (code == SUBREG && subreg_p) { - machine_mode mode = GET_MODE (*loc); + rtx subst, inner = SUBREG_REG (x); + /* Transform subreg of constant while we still have inner mode + of the subreg. The subreg internal should not be an insn + operand. */ + if (REG_P (inner) && (int) REGNO (inner) == old_regno + && CONSTANT_P (new_reg) + && (subst = simplify_subreg (GET_MODE (x), new_reg, GET_MODE (inner), + SUBREG_BYTE (x))) != NULL_RTX) + { + *loc = subst; + return true; + } + + } + else if (code == REG && (int) REGNO (x) == old_regno) + { + machine_mode mode = GET_MODE (x); machine_mode inner_mode = GET_MODE (new_reg); if (mode != inner_mode @@ -1815,26 +1832,30 @@ lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg) { if (fmt[i] == 'e') { - if (lra_substitute_pseudo (&XEXP (x, i), old_regno, new_reg)) + if (lra_substitute_pseudo (&XEXP (x, i), old_regno, + new_reg, subreg_p)) result = true; } else if (fmt[i] == 'E') { for (j = XVECLEN (x, i) - 1; j >= 0; j--) - if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno, new_reg)) + if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno, + new_reg, subreg_p)) result = true; } } return result; } -/* Call lra_substitute_pseudo within an insn. This won't update the insn ptr, - just the contents of the insn. */ +/* Call lra_substitute_pseudo within an insn. Try to simplify subreg + of constant if SUBREG_P. This won't update the insn ptr, just the + contents of the insn. */ bool -lra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno, rtx new_reg) +lra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno, + rtx new_reg, bool subreg_p) { rtx loc = insn; - return lra_substitute_pseudo (&loc, old_regno, new_reg); + return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p); } |