patch to fix PR92796

Message ID b777517a-44d0-aeb0-dc58-2df3c06a68c3@redhat.com
State New
Headers show
Series
  • patch to fix PR92796
Related show

Commit Message

Vladimir Makarov Dec. 10, 2019, 10:11 p.m.
The following patch fixes

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

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

Committed as r279204

Patch

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 279200)
+++ ChangeLog	(working copy)
@@ -1,3 +1,18 @@ 
+2019-12-10  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR rtl-optimization/92796
+	* lra-int.h (lra_risky_transformations_p): Rename to
+	check_and_force_assignment_correctness_p.
+	* lra-assigns.c: Ditto.
+	(lra_assign): Reset check_and_force_assignment_correctness_p.
+	* lra-constraints.c (lra_risky_transformations_p): Rename to
+	check_and_force_assignment_correctness_p.
+	(lra_constraints): Set up check_and_force_assignment_correctness_p
+	only for the 1st sub-pass.
+	* lra-eliminations.c (process_insn_for_elimination): Set up
+	check_and_force_assignment_correctness_p if the insn chnaged its
+	code.
+
 2019-12-10  Jakub Jelinek  <jakub@redhat.com>
 
 	PR rtl-optimization/92882
Index: lra-assigns.c
===================================================================
--- lra-assigns.c	(revision 278608)
+++ lra-assigns.c	(working copy)
@@ -1131,7 +1131,7 @@  static int *sorted_pseudos;
 /* The constraints pass is allowed to create equivalences between
    pseudos that make the current allocation "incorrect" (in the sense
    that pseudos are assigned to hard registers from their own conflict
-   sets).  The global variable lra_risky_transformations_p says
+   sets).  The global variable check_and_force_assignment_correctness_p says
    whether this might have happened.
 
    Process pseudos assigned to hard registers (less frequently used
@@ -1152,7 +1152,7 @@  setup_live_pseudos_and_spill_after_risky
   bitmap_iterator bi;
   int max_regno = max_reg_num ();
 
-  if (! lra_risky_transformations_p)
+  if (! check_and_force_assignment_correctness_p)
     {
       for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
 	if (reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
@@ -1690,6 +1690,8 @@  lra_assign (bool &fails_p)
     internal_error
       ("maximum number of LRA assignment passes is achieved (%d)",
        LRA_MAX_ASSIGNMENT_ITERATION_NUMBER);
+  /* Reset the assignment correctness flag: */
+  check_and_force_assignment_correctness_p = false;
   return no_spills_p;
 }
 
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 278608)
+++ lra-constraints.c	(working copy)
@@ -4665,11 +4665,14 @@  loc_equivalence_callback (rtx loc, const
 /* The current iteration number of this LRA pass.  */
 int lra_constraint_iter;
 
-/* True if we substituted equiv which needs checking register
-   allocation correctness because the equivalent value contains
-   allocatable hard registers or when we restore multi-register
-   pseudo.  */
-bool lra_risky_transformations_p;
+/* True if we should during assignment sub-pass check assignment
+   correctness for all pseudos and spill some of them to correct
+   conflicts.  It can be necessary when we substitute equiv which
+   needs checking register allocation correctness because the
+   equivalent value contains allocatable hard registers, or when we
+   restore multi-register pseudo, or when we change the insn code and
+   its operand became INOUT operand when it was IN one before.  */
+bool check_and_force_assignment_correctness_p;
 
 /* Return true if REGNO is referenced in more than one block.  */
 static bool
@@ -4811,14 +4814,14 @@  lra_constraints (bool first_p)
   changed_p = false;
   if (pic_offset_table_rtx
       && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER)
-    lra_risky_transformations_p = true;
-  else
+    check_and_force_assignment_correctness_p = true;
+  else if (first_p)
     /* On the first iteration we should check IRA assignment
        correctness.  In rare cases, the assignments can be wrong as
        early clobbers operands are ignored in IRA or usages of
        paradoxical sub-registers are not taken into account by
        IRA.  */
-    lra_risky_transformations_p = first_p;
+    check_and_force_assignment_correctness_p = true;
   new_insn_uid_start = get_max_uid ();
   new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num ();
   /* Mark used hard regs for target stack size calulations.  */
@@ -4994,7 +4997,7 @@  lra_constraints (bool first_p)
 		      dump_insn_slim (lra_dump_file, curr_insn);
 		    }
 		  if (contains_reg_p (x, true, false))
-		    lra_risky_transformations_p = true;
+		    check_and_force_assignment_correctness_p = true;
 		  lra_set_insn_deleted (curr_insn);
 		  continue;
 		}
@@ -5507,7 +5510,7 @@  need_for_split_p (HARD_REG_SET potential
 	   /* Don't split call clobbered hard regs living through
 	      calls, otherwise we might have a check problem in the
 	      assign sub-pass as in the most cases (exception is a
-	      situation when lra_risky_transformations_p value is
+	      situation when check_and_force_assignment_correctness_p value is
 	      true) the assign pass assumes that all pseudos living
 	      through calls are assigned to call saved hard regs.  */
 	   && (regno >= FIRST_PSEUDO_REGISTER
@@ -5799,7 +5802,7 @@  split_reg (bool before_p, int original_r
        sub-register levels, LRA do this on pseudos level right now and
        this discrepancy may create allocation conflicts after
        splitting.  */
-    lra_risky_transformations_p = true;
+    check_and_force_assignment_correctness_p = true;
   if (lra_dump_file != NULL)
     fprintf (lra_dump_file,
 	     "	  ))))))))))))))))))))))))))))))))))))))))))))))))\n");
@@ -6561,7 +6564,7 @@  inherit_in_ebb (rtx_insn *head, rtx_insn
 						 before_p, curr_insn, max_uid))
 			{
 			  if (reg->subreg_p)
-			    lra_risky_transformations_p = true;
+			    check_and_force_assignment_correctness_p = true;
 			  change_p = true;
 			  /* Invalidate. */
 			  usage_insns[src_regno].check = 0;
Index: lra-eliminations.c
===================================================================
--- lra-eliminations.c	(revision 278608)
+++ lra-eliminations.c	(working copy)
@@ -1311,6 +1311,11 @@  process_insn_for_elimination (rtx_insn *
 
       if (icode >= 0 && icode != INSN_CODE (insn))
 	{
+	  if (INSN_CODE (insn) >= 0)
+	    /* Insn code is changed.  It may change its operand type
+	       from IN to INOUT.  Inform the subsequent assignment
+	       subpass about this situation.  */
+	    check_and_force_assignment_correctness_p = true;
 	  INSN_CODE (insn) = icode;
 	  lra_update_insn_recog_data (insn);
 	}
Index: lra-int.h
===================================================================
--- lra-int.h	(revision 278413)
+++ lra-int.h	(working copy)
@@ -337,7 +337,7 @@  extern void lra_init_equiv (void);
 extern int lra_constraint_offset (int, machine_mode);
 
 extern int lra_constraint_iter;
-extern bool lra_risky_transformations_p;
+extern bool check_and_force_assignment_correctness_p;
 extern int lra_inheritance_iter;
 extern int lra_undo_inheritance_iter;
 extern bool lra_constrain_insn (rtx_insn *);
Index: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog	(revision 279200)
+++ testsuite/ChangeLog	(working copy)
@@ -1,3 +1,8 @@ 
+2019-12-10  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR rtl-optimization/92796
+	* gcc.target/powerpc/pr92796.c: New test.
+
 2019-12-10  Jakub Jelinek  <jakub@redhat.com>
 
 	PR rtl-optimization/92882
Index: testsuite/gcc.target/powerpc/pr92796.c
===================================================================
--- testsuite/gcc.target/powerpc/pr92796.c	(nonexistent)
+++ testsuite/gcc.target/powerpc/pr92796.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-protector-strong -mcpu=power8" } */
+
+typedef union
+{
+  __ieee128 a;
+  int b;
+} c;
+
+__ieee128
+d (__ieee128 x)
+{
+  __ieee128 g;
+  c h;
+  h.a = x;
+  g = h.b & 5;
+  h.b = g;
+  if (g)
+    return x - x;
+  return h.a;
+}