From b28ece323223adc71ea3c6d924d946ae67186153 Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Fri, 23 Nov 2012 01:29:07 +0000 Subject: [PATCH] re PR middle-end/55430 (LRA miscompilation of ree.c) 2012-11-22 Vladimir Makarov PR middle-end/55430 * lra.c: Move #include "hard-reg-set.h" before #include "rtl.h". (new_insn_reg): Update biggest_mode. (collect_non_operand_hard_regs): Check eliminable regs too. (initialize_lra_reg_info_element): Initialize biggest_mode. (add_regs_to_insn_regno_info): Ignore non-allocatable non-eliminable hard regs. (lra.c): Move setting lra_no_alloc_regs before init_insn_recog_data. * lra-constraints.c (simplify_operand_subreg): Add a comment. (lra_constraints): Ignore equivalent memory of regs occuring in paradoxical subregs. * lra-lives.c (lra_create_live_ranges): Add a comment. From-SVN: r193742 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/lra-constraints.c | 14 ++++++++++++-- gcc/lra-lives.c | 4 ++++ gcc/lra.c | 16 ++++++++++++---- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9bd49a877de..8a2fc8f556f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2012-11-22 Vladimir Makarov + + PR middle-end/55430 + * lra.c: Move #include "hard-reg-set.h" before #include "rtl.h". + (new_insn_reg): Update biggest_mode. + (collect_non_operand_hard_regs): Check eliminable regs too. + (initialize_lra_reg_info_element): Initialize biggest_mode. + (add_regs_to_insn_regno_info): Ignore non-allocatable + non-eliminable hard regs. + (lra.c): Move setting lra_no_alloc_regs before + init_insn_recog_data. + * lra-constraints.c (simplify_operand_subreg): Add a comment. + (lra_constraints): Ignore equivalent memory of + regs occuring in paradoxical subregs. + * lra-lives.c (lra_create_live_ranges): Add a comment. + 2012-11-22 Dmitry Vyukov Wei Mi diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 7fbd3d5e7fe..e381c704227 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1146,7 +1146,12 @@ simplify_operand_subreg (int nop, enum machine_mode reg_mode) reg = SUBREG_REG (operand); /* If we change address for paradoxical subreg of memory, the address might violate the necessary alignment or the access might - be slow. So take this into consideration. */ + be slow. So take this into consideration. We should not worry + about access beyond allocated memory for paradoxical memory + subregs as we don't substitute such equiv memory (see processing + equivalences in function lra_constraints) and because for spilled + pseudos we allocate stack memory enough for the biggest + corresponding paradoxical subreg. */ if ((MEM_P (reg) && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (reg)) || MEM_ALIGN (reg) >= GET_MODE_ALIGNMENT (mode))) @@ -3363,7 +3368,12 @@ lra_constraints (bool first_p) && (set = single_set (insn)) != NULL_RTX && REG_P (SET_DEST (set)) && (int) REGNO (SET_DEST (set)) == i) - && init_insn_rhs_dead_pseudo_p (i))) + && init_insn_rhs_dead_pseudo_p (i)) + /* Prevent access beyond equivalent memory for + paradoxical subregs. */ + || (MEM_P (x) + && (GET_MODE_SIZE (lra_reg_info[i].biggest_mode) + > GET_MODE_SIZE (GET_MODE (x))))) ira_reg_equiv[i].defined_p = false; if (contains_reg_p (x, false, true)) ira_reg_equiv[i].profitable_p = false; diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index f2dc359c18b..c79b95bf536 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -935,6 +935,10 @@ lra_create_live_ranges (bool all_p) #ifdef STACK_REGS lra_reg_info[i].no_stack_p = false; #endif + /* The biggest mode is already set but its value might be to + conservative because of recent transformation. Here in this + file we recalculate it again as it costs practically + nothing. */ if (regno_reg_rtx[i] != NULL_RTX) lra_reg_info[i].biggest_mode = GET_MODE (regno_reg_rtx[i]); else diff --git a/gcc/lra.c b/gcc/lra.c index 35b53eccaa5..80bf4328d9b 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -97,6 +97,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" +#include "hard-reg-set.h" #include "rtl.h" #include "tm_p.h" #include "regs.h" @@ -105,7 +106,6 @@ along with GCC; see the file COPYING3. If not see #include "recog.h" #include "output.h" #include "addresses.h" -#include "hard-reg-set.h" #include "flags.h" #include "function.h" #include "expr.h" @@ -461,6 +461,8 @@ new_insn_reg (int regno, enum op_type type, enum machine_mode mode, ir = (struct lra_insn_reg *) pool_alloc (insn_reg_pool); ir->type = type; ir->biggest_mode = mode; + if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode)) + lra_reg_info[regno].biggest_mode = mode; ir->subreg_p = subreg_p; ir->early_clobber = early_clobber; ir->regno = regno; @@ -916,7 +918,8 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data, for (last = regno + hard_regno_nregs[regno][mode]; regno < last; regno++) - if (! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)) + if (! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno) + || TEST_HARD_REG_BIT (eliminable_regset, regno)) { for (curr = list; curr != NULL; curr = curr->next) if (curr->regno == regno && curr->subreg_p == subreg_p @@ -1384,6 +1387,7 @@ initialize_lra_reg_info_element (int i) lra_reg_info[i].preferred_hard_regno2 = -1; lra_reg_info[i].preferred_hard_regno_profit1 = 0; lra_reg_info[i].preferred_hard_regno_profit2 = 0; + lra_reg_info[i].biggest_mode = VOIDmode; lra_reg_info[i].live_ranges = NULL; lra_reg_info[i].nrefs = lra_reg_info[i].freq = 0; lra_reg_info[i].last_reload = 0; @@ -1530,6 +1534,10 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid, if (REG_P (x)) { regno = REGNO (x); + if (regno < FIRST_PSEUDO_REGISTER + && TEST_HARD_REG_BIT (lra_no_alloc_regs, regno) + && ! TEST_HARD_REG_BIT (eliminable_regset, regno)) + return; expand_reg_info (); if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid)) { @@ -2202,14 +2210,14 @@ lra (FILE *f) timevar_push (TV_LRA); + COPY_HARD_REG_SET (lra_no_alloc_regs, ira_no_alloc_regs); + init_insn_recog_data (); #ifdef ENABLE_CHECKING check_rtl (false); #endif - COPY_HARD_REG_SET (lra_no_alloc_regs, ira_no_alloc_regs); - lra_live_range_iter = lra_coalesce_iter = 0; lra_constraint_iter = lra_constraint_iter_after_spill = 0; lra_inheritance_iter = lra_undo_inheritance_iter = 0; -- 2.30.2