diff mbox

patch for PR66691 backported to gcc5

Message ID 55BB7E1E.5090905@redhat.com
State New
Headers show

Commit Message

Vladimir Makarov July 31, 2015, 1:54 p.m. UTC
The following patch was committed to gcc5 branch as rev. 226442.

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

     2015-07-31  Vladimir Makarov  <vmakarov@redhat.com>

         PR debug/66691
         * lra-int.h (lra_substitute_pseudo): Add a parameter.
         (lra_substitute_pseudo_within_insn): Ditto.
         * lra.c (lra_substitute_pseudo): Add a parameter.  Simplify subreg
         of constant.
         (lra_substitute_pseudo_within_insn): Add a parameter. Transfer it
         to lra_substitute_pseudo.
         * lra-lives.c (process_bb_lives): Add an argument to
         lra_substitute_pseudo_within_insn call.
         * lra-constraints.c (inherit_reload_reg, split_reg): Add an
         argument to lra_substitute_pseudo and
         lra_substitute_pseudo_within_insn calls.
         (remove_inheritance_pseudos, undo_optional_reloads): Ditto.

2015-07-31  Vladimir Makarov  <vmakarov@redhat.com>

         PR debug/66691
         * gcc.target/i386/pr66691.c: New.
diff mbox

Patch

Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 226441)
+++ lra-constraints.c	(working copy)
@@ -4729,7 +4729,7 @@  inherit_reload_reg (bool def_p, int orig
 	}
       return false;
     }
-  lra_substitute_pseudo_within_insn (insn, original_regno, new_reg);
+  lra_substitute_pseudo_within_insn (insn, original_regno, new_reg, false);
   lra_update_insn_regno_info (insn);
   if (! def_p)
     /* We now have a new usage insn for original regno.  */
@@ -4761,7 +4761,7 @@  inherit_reload_reg (bool def_p, int orig
 	  lra_assert (DEBUG_INSN_P (usage_insn));
 	  next_usage_insns = XEXP (next_usage_insns, 1);
 	}
-      lra_substitute_pseudo (&usage_insn, original_regno, new_reg);
+      lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false);
       lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
       if (lra_dump_file != NULL)
 	{
@@ -5023,7 +5023,7 @@  split_reg (bool before_p, int original_r
       usage_insn = XEXP (next_usage_insns, 0);
       lra_assert (DEBUG_INSN_P (usage_insn));
       next_usage_insns = XEXP (next_usage_insns, 1);
-      lra_substitute_pseudo (&usage_insn, original_regno, new_reg);
+      lra_substitute_pseudo (&usage_insn, original_regno, new_reg, false);
       lra_update_insn_regno_info (as_a <rtx_insn *> (usage_insn));
       if (lra_dump_file != NULL)
 	{
@@ -5955,8 +5955,9 @@  remove_inheritance_pseudos (bitmap remov
 		    {
 		      if (change_p && bitmap_bit_p (remove_pseudos, regno))
 			{
-			  lra_substitute_pseudo_within_insn (
-			    curr_insn, regno, regno_reg_rtx[restore_regno]);
+			  lra_substitute_pseudo_within_insn
+			    (curr_insn, regno, regno_reg_rtx[restore_regno],
+			     false);
 			  restored_regs_p = true;
 			}
 		      else
@@ -6079,9 +6080,9 @@  undo_optional_reloads (void)
 		 we remove the inheritance pseudo and the optional
 		 reload.  */
 	    }
-	  lra_substitute_pseudo_within_insn (
-	    insn, regno,
-	    regno_reg_rtx[lra_reg_info[regno].restore_regno]);
+	  lra_substitute_pseudo_within_insn
+	    (insn, regno, regno_reg_rtx[lra_reg_info[regno].restore_regno],
+	     false);
 	  lra_update_insn_regno_info (insn);
 	  if (lra_dump_file != NULL)
 	    {
Index: lra-int.h
===================================================================
--- lra-int.h	(revision 226441)
+++ lra-int.h	(working copy)
@@ -314,8 +314,8 @@  extern void lra_update_dups (lra_insn_re
 extern void lra_process_new_insns (rtx_insn *, rtx_insn *, rtx_insn *,
 				   const char *);
 
-extern bool lra_substitute_pseudo (rtx *, int, rtx);
-extern bool lra_substitute_pseudo_within_insn (rtx_insn *, int, rtx);
+extern bool lra_substitute_pseudo (rtx *, int, rtx, bool);
+extern bool lra_substitute_pseudo_within_insn (rtx_insn *, int, rtx, bool);
 
 extern lra_insn_recog_data_t lra_set_insn_recog_data (rtx_insn *);
 extern lra_insn_recog_data_t lra_update_insn_recog_data (rtx_insn *);
Index: lra-lives.c
===================================================================
--- lra-lives.c	(revision 226441)
+++ lra-lives.c	(working copy)
@@ -759,7 +759,7 @@  process_bb_lives (basic_block bb, int &c
 		    {
 		      insn = lra_insn_recog_data[uid]->insn;
 		      lra_substitute_pseudo_within_insn (insn, dst_regno,
-							 SET_SRC (set));
+							 SET_SRC (set), true);
 		      lra_update_insn_regno_info (insn);
 		    }
 		}
Index: lra.c
===================================================================
--- lra.c	(revision 226441)
+++ lra.c	(working copy)
@@ -1818,9 +1818,10 @@  lra_process_new_insns (rtx_insn *insn, r
 
 
 /* Replace all references to register OLD_REGNO in *LOC with pseudo
-   register NEW_REG.  Return true if any change was made.  */
+   register NEW_REG.  Try to simplify subreg of constant if SUBREG_P.
+   Return true if any change was made.  */
 bool
-lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg)
+lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p)
 {
   rtx x = *loc;
   bool result = false;
@@ -1832,9 +1833,25 @@  lra_substitute_pseudo (rtx *loc, int old
     return false;
 
   code = GET_CODE (x);
-  if (code == REG && (int) REGNO (x) == old_regno)
+  if (code == SUBREG && subreg_p)
     {
-      machine_mode mode = GET_MODE (*loc);
+      rtx subst, inner = SUBREG_REG (x);
+      /* Transform subreg of constant while we still have inner mode
+	 of the subreg.  The subreg internal should not be an insn
+	 operand.  */
+      if (REG_P (inner) && (int) REGNO (inner) == old_regno
+	  && CONSTANT_P (new_reg)
+	  && (subst = simplify_subreg (GET_MODE (x), new_reg, GET_MODE (inner),
+				       SUBREG_BYTE (x))) != NULL_RTX)
+	{
+	  *loc = subst;
+	  return true;
+	}
+      
+    }
+  else if (code == REG && (int) REGNO (x) == old_regno)
+    {
+      machine_mode mode = GET_MODE (x);
       machine_mode inner_mode = GET_MODE (new_reg);
 
       if (mode != inner_mode
@@ -1856,26 +1873,30 @@  lra_substitute_pseudo (rtx *loc, int old
     {
       if (fmt[i] == 'e')
 	{
-	  if (lra_substitute_pseudo (&XEXP (x, i), old_regno, new_reg))
+	  if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
+				     new_reg, subreg_p))
 	    result = true;
 	}
       else if (fmt[i] == 'E')
 	{
 	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-	    if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno, new_reg))
+	    if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno,
+				       new_reg, subreg_p))
 	      result = true;
 	}
     }
   return result;
 }
 
-/* Call lra_substitute_pseudo within an insn.  This won't update the insn ptr,
-   just the contents of the insn.  */
+/* Call lra_substitute_pseudo within an insn.  Try to simplify subreg
+   of constant if SUBREG_P.  This won't update the insn ptr, just the
+   contents of the insn.  */
 bool
-lra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno, rtx new_reg)
+lra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno,
+				   rtx new_reg, bool subreg_p)
 {
   rtx loc = insn;
-  return lra_substitute_pseudo (&loc, old_regno, new_reg);
+  return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p);
 }
 
 
Index: testsuite/gcc.target/i386/pr66691.c
===================================================================
--- testsuite/gcc.target/i386/pr66691.c	(revision 0)
+++ testsuite/gcc.target/i386/pr66691.c	(working copy)
@@ -0,0 +1,64 @@ 
+/* PR debug/66691 */
+/* { dg-do compile } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-O3 -g -mtune=generic -march=i686" } */
+
+unsigned int a;
+int b[2], c, d, e, f, g, h, i, k[8], l, m, s, t, w;
+static int j;
+
+void
+fn1 (long long p)
+{
+  int t = p;
+  c = c ^ b[c ^ (t & 1)];
+}
+
+static void
+fn2 (long long p)
+{
+  c = c ^ b[1 ^ (d & 1)];
+  fn1 (p >> 1 & 1);
+  fn1 (p >> 2);
+}
+
+static void
+fn3 ()
+{
+  unsigned char p;
+  f = g = 0;
+  for (h = 0; h < 6; h++)
+    {
+      for (s = 0; s < 7; s++)
+	if (k[s+1])
+	  g = 0;
+	else
+	  for (j = 0; j < 2; j++)
+	    ;
+      t = j > 2 ? 0 : 1 >> j;
+    }
+  if (l)
+    {
+      short q[2];
+      q[0] = q[1] = 0;
+      if (m)
+	for (i = 0; i < 2; i++)
+	  {
+	    unsigned char r = q[i];
+	    p = f ? r % f : r;
+	    e = ((p > 0) <= (q[i] ^ 1)) + a;
+	    if (k[1])
+	      for (e = 0; e != 18; ++e)
+		k[0] = 0;
+	  }
+    }
+}
+
+int
+main ()
+{
+  fn3 ();
+  fn2 (w);
+  fn2 (j);
+  return 0;
+}