diff mbox series

patch to fix PR84876

Message ID 78806caf-f7be-e0b3-9b06-64df853b26f3@redhat.com
State New
Headers show
Series patch to fix PR84876 | expand

Commit Message

Vladimir Makarov March 16, 2018, 6:54 p.m. UTC
The following patch fixes

   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84876

and another problem with LRA cycling which occurred on the same test.

The patch was successfully bootstrapped and tested on i686 and x86_64.

Committed as rev. 258602.
diff mbox series

Patch

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 258601)
+++ ChangeLog	(working copy)
@@ -1,3 +1,11 @@ 
+2018-03-16  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR target/84876
+	* lra-assigns.c (lra_split_hard_reg_for): Don't use
+	regno_allocno_class_array and sorted_pseudos.
+	* lra-constraints.c (spill_hard_reg_in_range): Ignore hard regs in
+	insns where regno is used.
+
 2018-03-16  Martin Liska  <mliska@suse.cz>
 
 	PR ipa/84833
Index: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog	(revision 258601)
+++ testsuite/ChangeLog	(working copy)
@@ -1,3 +1,8 @@ 
+2018-03-16  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR target/84876
+	* gcc.target/i386/pr84876.c: New test.
+
 2018-03-16  Martin Liska  <mliska@suse.cz>
 
 	PR ipa/84833
Index: lra-assigns.c
===================================================================
--- lra-assigns.c	(revision 258504)
+++ lra-assigns.c	(working copy)
@@ -1737,41 +1737,46 @@  find_reload_regno_insns (int regno, rtx_
 bool
 lra_split_hard_reg_for (void)
 {
-  int i, regno, n;
+  int i, regno;
   rtx_insn *insn, *first, *last;
   unsigned int u;
   bitmap_iterator bi;
+  enum reg_class rclass;
   int max_regno = max_reg_num ();
   /* We did not assign hard regs to reload pseudos after two
      iterations.  Either it's an asm and something is wrong with the
      constraints, or we have run out of spill registers; error out in
      either case.  */
   bool asm_p = false;
-  bitmap_head failed_reload_insns;
+  bitmap_head failed_reload_insns, failed_reload_pseudos;
   
   if (lra_dump_file != NULL)
     fprintf (lra_dump_file,
 	     "\n****** Splitting a hard reg after assignment #%d: ******\n\n",
 	     lra_assignment_iter);
-  for (n = 0, i = lra_constraint_new_regno_start; i < max_regno; i++)
+  bitmap_initialize (&failed_reload_pseudos, &reg_obstack);
+  for (i = lra_constraint_new_regno_start; i < max_regno; i++)
     if (reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0
-	&& regno_allocno_class_array[i] != NO_REGS
+	&& (rclass = lra_get_allocno_class (i)) != NO_REGS
 	&& ! bitmap_bit_p (&non_reload_pseudos, i))
       {
-	sorted_pseudos[n++] = i;
 	if (! find_reload_regno_insns (i, first, last))
 	  continue;
-	if (spill_hard_reg_in_range (i, regno_allocno_class_array[i],
-				     first, last))
-	  return true;
+	if (spill_hard_reg_in_range (i, rclass, first, last))
+	  {
+	    bitmap_clear (&failed_reload_pseudos);
+	    return true;
+	  }
+	bitmap_set_bit (&failed_reload_pseudos, i);
       }
   bitmap_initialize (&failed_reload_insns, &reg_obstack);
-  for (i = 0; i < n; i++)
+  EXECUTE_IF_SET_IN_BITMAP (&failed_reload_pseudos, 0, u, bi)
     {
-      regno = sorted_pseudos[i];
+      regno = u;
       bitmap_ior_into (&failed_reload_insns,
 		       &lra_reg_info[regno].insn_bitmap);
-      lra_setup_reg_renumber (regno, ira_class_hard_regs[regno_allocno_class_array[regno]][0], false);
+      lra_setup_reg_renumber
+	(regno, ira_class_hard_regs[lra_get_allocno_class (regno)][0], false);
     }
   EXECUTE_IF_SET_IN_BITMAP (&failed_reload_insns, 0, u, bi)
     {
@@ -1805,5 +1810,7 @@  lra_split_hard_reg_for (void)
 	  fatal_insn ("this is the insn:", insn);
 	}
     }
+  bitmap_clear (&failed_reload_pseudos);
+  bitmap_clear (&failed_reload_insns);
   return false;
 }
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 258504)
+++ lra-constraints.c	(working copy)
@@ -5680,13 +5680,30 @@  spill_hard_reg_in_range (int regno, enum
   int i, hard_regno;
   int rclass_size;
   rtx_insn *insn;
+  unsigned int uid;
+  bitmap_iterator bi;
+  HARD_REG_SET ignore;
   
   lra_assert (from != NULL && to != NULL);
+  CLEAR_HARD_REG_SET (ignore);
+  EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi)
+    {
+      lra_insn_recog_data_t id = lra_insn_recog_data[uid];
+      struct lra_static_insn_data *static_id = id->insn_static_data;
+      struct lra_insn_reg *reg;
+      
+      for (reg = id->regs; reg != NULL; reg = reg->next)
+	if (reg->regno <= FIRST_PSEUDO_REGISTER)
+	  SET_HARD_REG_BIT (ignore, reg->regno);
+      for (reg = static_id->hard_regs; reg != NULL; reg = reg->next)
+	SET_HARD_REG_BIT (ignore, reg->regno);
+    }
   rclass_size = ira_class_hard_regs_num[rclass];
   for (i = 0; i < rclass_size; i++)
     {
       hard_regno = ira_class_hard_regs[rclass][i];
-      if (! TEST_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, hard_regno))
+      if (! TEST_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, hard_regno)
+	  || TEST_HARD_REG_BIT (ignore, hard_regno))
 	continue;
       for (insn = from; insn != NEXT_INSN (to); insn = NEXT_INSN (insn))
 	if (bitmap_bit_p (&lra_reg_info[hard_regno].insn_bitmap,
Index: testsuite/gcc.target/i386/pr84876.c
===================================================================
--- testsuite/gcc.target/i386/pr84876.c	(nonexistent)
+++ testsuite/gcc.target/i386/pr84876.c	(working copy)
@@ -0,0 +1,11 @@ 
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-w" } */
+
+__int128 test (__int128 a)
+{
+  asm ("" : "+v" (a) : : "xmm0", "xmm1", "xmm2", "xmm3", /* { dg-error "'asm' operand has impossible constraints" } */
+			 "xmm4", "xmm5", "xmm6", "xmm7",
+			 "xmm8", "xmm9", "xmm10", "xmm11",
+			 "xmm12", "xmm13", "xmm14", "xmm15");
+  return a;
+}