diff mbox

patch to fix PR55430

Message ID 50AED180.6070305@redhat.com
State New
Headers show

Commit Message

Vladimir Makarov Nov. 23, 2012, 1:29 a.m. UTC
The following patch fixes

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55430

   The patch was successfully bootstrapped and tested on x86/x86-64.

   Committed as rev. 193742.

2012-11-22  Vladimir Makarov  <vmakarov@redhat.com>

         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.

Comments

H.J. Lu Nov. 23, 2012, 7:50 a.m. UTC | #1
On Thu, Nov 22, 2012 at 5:29 PM, Vladimir Makarov <vmakarov@redhat.com> wrote:
>   The following patch fixes
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55430
>
>   The patch was successfully bootstrapped and tested on x86/x86-64.
>
>   Committed as rev. 193742.
>
> 2012-11-22  Vladimir Makarov  <vmakarov@redhat.com>
>
>         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.
>
>

On Linux/x86-64, this caused:

FAIL: gcc.target/i386/avx-vzeroupper-16.c (internal compiler error)
FAIL: gcc.target/i386/avx-vzeroupper-16.c (test for excess errors)
FAIL: gcc.target/i386/avx-vzeroupper-17.c (internal compiler error)
FAIL: gcc.target/i386/avx-vzeroupper-17.c (test for excess errors)
FAIL: gcc.target/i386/avx-vzeroupper-18.c (internal compiler error)
FAIL: gcc.target/i386/avx-vzeroupper-18.c (test for excess errors)
FAIL: gcc.target/i386/pr43869.c (internal compiler error)
FAIL: gcc.target/i386/pr43869.c (test for excess errors)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-1.c (internal compiler error)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-1.c (test for excess errors)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-3.c (internal compiler error)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-3.c (test for excess errors)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-4a.c (internal compiler error)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-4a.c (test for excess errors)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-4b.c (internal compiler error)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-4b.c (test for excess errors)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-5a.c (internal compiler error)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-5a.c (test for excess errors)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-5b.c (internal compiler error)
FAIL: gcc.target/x86_64/abi/callabi/vaarg-5b.c (test for excess errors)
diff mbox

Patch

Index: lra.c
===================================================================
--- lra.c	(revision 193702)
+++ lra.c	(working copy)
@@ -97,6 +97,7 @@  along with GCC; see the file COPYING3.	I
 #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.	I
 #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 ty
   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, l
       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_re
   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;
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 193712)
+++ lra-constraints.c	(working copy)
@@ -1146,7 +1146,12 @@  simplify_operand_subreg (int nop, enum m
   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;
Index: lra-lives.c
===================================================================
--- lra-lives.c	(revision 193702)
+++ lra-lives.c	(working copy)
@@ -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