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  <vmaka...@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  <vmaka...@redhat.com>

         PR rtl-optimization/59477
         * g++.dg/pr59477.C: New.

ENOPATCH ;)

        Jakub

Ops, sorry.  The patch is in the attachment.

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));
+}

Reply via email to