From ef87312ec1246b8667da99e34ecfacff595c9c21 Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Tue, 30 Jun 2015 17:40:55 +0000 Subject: [PATCH] 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 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 PR debug/66691 * gcc.target/i386/pr66691.c: New. From-SVN: r225200 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/lra-constraints.c | 17 +++++++++-------- gcc/lra-int.h | 4 ++-- gcc/lra-lives.c | 2 +- gcc/lra.c | 41 +++++++++++++++++++++++++++++++---------- gcc/testsuite/ChangeLog | 5 +++++ 6 files changed, 64 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c027d8e34f0..83f598676f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2015-06-30 Vladimir Makarov + + 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 H.J. Lu * configure: Regenerated. diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 1d3f94e5ab0..75c2a77b3dc 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -4711,7 +4711,7 @@ inherit_reload_reg (bool def_p, int original_regno, } return false; } - lra_substitute_pseudo_within_insn (insn, original_regno, new_reg); + lra_substitute_pseudo_within_insn (insn, original_regno, new_reg, false); lra_update_insn_regno_info (insn); if (! def_p) /* We now have a new usage insn for original regno. */ @@ -4743,7 +4743,7 @@ inherit_reload_reg (bool def_p, int original_regno, lra_assert (DEBUG_INSN_P (usage_insn)); next_usage_insns = XEXP (next_usage_insns, 1); } - lra_substitute_pseudo (&usage_insn, original_regno, new_reg); + lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false); lra_update_insn_regno_info (as_a (usage_insn)); if (lra_dump_file != NULL) { @@ -5005,7 +5005,7 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn, usage_insn = XEXP (next_usage_insns, 0); lra_assert (DEBUG_INSN_P (usage_insn)); next_usage_insns = XEXP (next_usage_insns, 1); - lra_substitute_pseudo (&usage_insn, original_regno, new_reg); + lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false); lra_update_insn_regno_info (as_a (usage_insn)); if (lra_dump_file != NULL) { @@ -5925,8 +5925,9 @@ remove_inheritance_pseudos (bitmap remove_pseudos) { if (change_p && bitmap_bit_p (remove_pseudos, regno)) { - lra_substitute_pseudo_within_insn ( - curr_insn, regno, regno_reg_rtx[restore_regno]); + lra_substitute_pseudo_within_insn + (curr_insn, regno, regno_reg_rtx[restore_regno], + false); restored_regs_p = true; } else @@ -6049,9 +6050,9 @@ undo_optional_reloads (void) we remove the inheritance pseudo and the optional reload. */ } - lra_substitute_pseudo_within_insn ( - insn, regno, - regno_reg_rtx[lra_reg_info[regno].restore_regno]); + lra_substitute_pseudo_within_insn + (insn, regno, regno_reg_rtx[lra_reg_info[regno].restore_regno], + false); lra_update_insn_regno_info (insn); if (lra_dump_file != NULL) { diff --git a/gcc/lra-int.h b/gcc/lra-int.h index 25bd3cefd81..e1d5ef2c918 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -358,8 +358,8 @@ extern void lra_update_dups (lra_insn_recog_data_t, signed char *); extern void lra_process_new_insns (rtx_insn *, rtx_insn *, rtx_insn *, const char *); -extern bool lra_substitute_pseudo (rtx *, int, rtx); -extern bool lra_substitute_pseudo_within_insn (rtx_insn *, int, rtx); +extern bool lra_substitute_pseudo (rtx *, int, rtx, bool); +extern bool lra_substitute_pseudo_within_insn (rtx_insn *, int, rtx, bool); extern lra_insn_recog_data_t lra_set_insn_recog_data (rtx_insn *); extern lra_insn_recog_data_t lra_update_insn_recog_data (rtx_insn *); diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 5157c85895e..88c0ef671b4 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -726,7 +726,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) { insn = lra_insn_recog_data[uid]->insn; lra_substitute_pseudo_within_insn (insn, dst_regno, - SET_SRC (set)); + SET_SRC (set), true); lra_update_insn_regno_info (insn); } } diff --git a/gcc/lra.c b/gcc/lra.c index 5d1f429658f..bdd8e3ca3df 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -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); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 33877d4d798..4f091541966 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-06-30 Vladimir Makarov + + PR debug/66691 + * gcc.target/i386/pr66691.c: New. + 2015-06-30 H.J. Lu * gcc.target/i386/iamcu/abi-iamcu.exp: New file. -- 2.30.2