Patch to fix PR93272

Message ID 2726f098-5c0a-bf10-cfd2-49ff29252d90@redhat.com
State New
Headers show
Series
  • Patch to fix PR93272
Related show

Commit Message

Vladimir Makarov Jan. 28, 2020, 8:52 p.m.
The following patch fixes

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

The patch was successfully tested and bootstrapped on x86_64.

Unfortunately it is hard to create a test case for the patch.  So there 
is no test for this PR.

Comments

Matthias Klose Feb. 24, 2020, 12:20 p.m. | #1
On 1/28/20 9:52 PM, Vladimir Makarov wrote:
> The following patch fixes

> 

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

> 

> The patch was successfully tested and bootstrapped on x86_64.

> 

> Unfortunately it is hard to create a test case for the patch.  So there is no

> test for this PR.


the bug report asks for a backport to the gcc-8 and gcc-9 branches.

Patch

commit 5c8a1211b9873a1b69ef7b2fddae181535bc3b0a (HEAD -> master, origin/master, origin/HEAD)
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Tue Jan 28 15:43:44 2020 -0500

    Fix for PR93272 - LRA: EH reg allocated to hold local variable
    
    2020-01-28  Vladimir Makarov  <vmakarov@redhat.com>
    
            PR rtl-optimization/93272
            * ira-lives.c (process_out_of_region_eh_regs): New function.
            (process_bb_node_lives): Call it.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 326250b9b96..8d60dcf0864 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@ 
+2020-01-28  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR rtl-optimization/93272
+	* ira-lives.c (process_out_of_region_eh_regs): New function.
+	(process_bb_node_lives): Call it.
+
 2020-01-28  Jan Hubicka  <hubicka@ucw.cz>
 
 	* coverage.c (read_counts_file): Make error message lowercase.
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 155f825ea8d..f776fd2342f 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -1160,6 +1160,50 @@  non_conflicting_reg_copy_p (rtx_insn *insn)
   return SET_SRC (set);
 }
 
+#ifdef EH_RETURN_DATA_REGNO
+
+/* Add EH return hard registers as conflict hard registers to allocnos
+   living at end of BB.  For most allocnos it is already done in
+   process_bb_node_lives when we processing input edges but it does
+   not work when and EH edge is edge out of the current region.  This
+   function covers such out of region edges. */
+static void
+process_out_of_region_eh_regs (basic_block bb)
+{
+  edge e;
+  edge_iterator ei;
+  unsigned int i;
+  bitmap_iterator bi;
+  bool eh_p = false;
+
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    if ((e->flags & EDGE_EH)
+	&& IRA_BB_NODE (e->dest)->parent != IRA_BB_NODE (bb)->parent)
+      eh_p = true;
+
+  if (! eh_p)
+    return;
+
+  EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb), FIRST_PSEUDO_REGISTER, i, bi)
+    {
+      ira_allocno_t a = ira_curr_regno_allocno_map[i];
+      for (int n = ALLOCNO_NUM_OBJECTS (a) - 1; n >= 0; n--)
+	{
+	  ira_object_t obj = ALLOCNO_OBJECT (a, n);
+	  for (int k = 0; ; k++)
+	    {
+	      unsigned int regno = EH_RETURN_DATA_REGNO (k);
+	      if (regno == INVALID_REGNUM)
+		break;
+	      SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
+	      SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno);
+	    }
+	}
+    }
+}
+
+#endif
+
 /* Process insns of the basic block given by its LOOP_TREE_NODE to
    update allocno live ranges, allocno hard register conflicts,
    intersected calls, and register pressure info for allocnos for the
@@ -1213,6 +1257,10 @@  process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
       EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
 	mark_pseudo_regno_live (j);
 
+#ifdef EH_RETURN_DATA_REGNO
+      process_out_of_region_eh_regs (bb);
+#endif
+
       freq = REG_FREQ_FROM_BB (bb);
       if (freq == 0)
 	freq = 1;