patch to fix PR59477

Vladimir Makarov vmakarov@redhat.com
Wed Jan 22 19:45:00 GMT 2014


On 1/22/2014, 2:41 PM, Jakub Jelinek wrote:
> On Wed, Jan 22, 2014 at 02:40:46PM -0500, Vladimir Makarov wrote:
>>    The following patch fixes
>>
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59477
>>
>>    The patch was successfully bootstrapped and tested on x86/x86-64.
>>
>>    Committed as rev. 206938.
>>
>> 2014-01-22  Vladimir Makarov  <vmakarov@redhat.com>
>>
>>          PR rtl-optimization/59477
>>          * lra-constraints.c (inherit_in_ebb): Process call for living hard
>>          regs.  Update reloads_num and potential_reload_hard_regs for all
>>          insns.
>>
>> 2014-01-22  Vladimir Makarov  <vmakarov@redhat.com>
>>
>>          PR rtl-optimization/59477
>>          * g++.dg/pr59477.C: New.
>
> ENOPATCH ;)
>
> 	Jakub
>
Ops, sorry.  The patch is in the attachment.

-------------- next part --------------
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 206686)
+++ lra-constraints.c	(working copy)
@@ -4992,7 +4992,7 @@
 inherit_in_ebb (rtx head, rtx tail)
 {
   int i, src_regno, dst_regno, nregs;
-  bool change_p, succ_p;
+  bool change_p, succ_p, update_reloads_num_p;
   rtx prev_insn, next_usage_insns, set, last_insn;
   enum reg_class cl;
   struct lra_insn_reg *reg;
@@ -5063,6 +5063,7 @@
 	  src_regno = REGNO (SET_SRC (set));
 	  dst_regno = REGNO (SET_DEST (set));
 	}
+      update_reloads_num_p = true;
       if (src_regno < lra_constraint_new_regno_start
 	  && src_regno >= FIRST_PSEUDO_REGISTER
 	  && reg_renumber[src_regno] < 0
@@ -5071,6 +5072,7 @@
 	{
 	  /* 'reload_pseudo <- original_pseudo'.  */
 	  reloads_num++;
+	  update_reloads_num_p = false;
 	  succ_p = false;
 	  if (usage_insns[src_regno].check == curr_usage_insns_check
 	      && (next_usage_insns = usage_insns[src_regno].insns) != NULL_RTX)
@@ -5094,6 +5096,7 @@
 		   = usage_insns[dst_regno].insns) != NULL_RTX)
 	{
 	  reloads_num++;
+	  update_reloads_num_p = false;
 	  /* 'original_pseudo <- reload_pseudo'.  */
 	  if (! JUMP_P (curr_insn)
 	      && inherit_reload_reg (true, dst_regno, cl,
@@ -5282,6 +5285,14 @@
 		      add_next_usage_insn (src_regno, use_insn, reloads_num);
 		    }
 		}
+	  /* Process call args.  */
+	  if (curr_id->arg_hard_regs != NULL)
+	    for (i = 0; (src_regno = curr_id->arg_hard_regs[i]) >= 0; i++)
+	      if (src_regno < FIRST_PSEUDO_REGISTER)
+		{
+	           SET_HARD_REG_BIT (live_hard_regs, src_regno);
+	           add_next_usage_insn (src_regno, curr_insn, reloads_num);
+		}
 	  for (i = 0; i < to_inherit_num; i++)
 	    {
 	      src_regno = to_inherit[i].regno;
@@ -5292,6 +5303,26 @@
 		setup_next_usage_insn (src_regno, curr_insn, reloads_num, false);
 	    }
 	}
+      if (update_reloads_num_p
+	  && NONDEBUG_INSN_P (curr_insn)
+          && (set = single_set (curr_insn)) != NULL_RTX)
+	{
+	  int regno = -1;
+	  if ((REG_P (SET_DEST (set))
+	       && (regno = REGNO (SET_DEST (set))) >= lra_constraint_new_regno_start
+	       && reg_renumber[regno] < 0
+	       && (cl = lra_get_allocno_class (regno)) != NO_REGS)
+	      || (REG_P (SET_SRC (set))
+	          && (regno = REGNO (SET_SRC (set))) >= lra_constraint_new_regno_start
+	          && reg_renumber[regno] < 0
+	          && (cl = lra_get_allocno_class (regno)) != NO_REGS))
+	    {
+	      reloads_num++;
+	      if (hard_reg_set_subset_p (reg_class_contents[cl], live_hard_regs))
+		IOR_HARD_REG_SET (potential_reload_hard_regs,
+	                          reg_class_contents[cl]);
+	    }
+	}
       /* We reached the start of the current basic block.  */
       if (prev_insn == NULL_RTX || prev_insn == PREV_INSN (head)
 	  || BLOCK_FOR_INSN (prev_insn) != curr_bb)
Index: testsuite/g++.dg/pr59477.C
===================================================================
--- testsuite/g++.dg/pr59477.C	(revision 0)
+++ testsuite/g++.dg/pr59477.C	(working copy)
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct A
+{
+  unsigned *a, b;
+  A (unsigned x) : a (), b (x) {}
+};
+
+struct B
+{
+  B (int);
+  B (const B &) {}
+};
+
+B bar (B, B, A);
+int v;
+
+void
+foo ()
+{
+  B c = 0;
+  bar (c, c, A (1ULL << v));
+}


More information about the Gcc-patches mailing list