re PR debug/66691 (ICE on valid code at -O3 with -g enabled in simplify_subreg, at...
authorVladimir Makarov <vmakarov@redhat.com>
Tue, 30 Jun 2015 17:40:55 +0000 (17:40 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Tue, 30 Jun 2015 17:40:55 +0000 (17:40 +0000)
2015-06-30  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-06-30  Vladimir Makarov  <vmakarov@redhat.com>

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

From-SVN: r225200

gcc/ChangeLog
gcc/lra-constraints.c
gcc/lra-int.h
gcc/lra-lives.c
gcc/lra.c
gcc/testsuite/ChangeLog

index c027d8e..83f5986 100644 (file)
@@ -1,3 +1,19 @@
+2015-06-30  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-06-30  H.J. Lu  <hongjiu.lu@intel.com>
 
        * configure: Regenerated.
index 1d3f94e..75c2a77 100644 (file)
@@ -4711,7 +4711,7 @@ inherit_reload_reg (bool def_p, int original_regno,
        }
       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.  */
@@ -4743,7 +4743,7 @@ inherit_reload_reg (bool def_p, int original_regno,
          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)
        {
@@ -5005,7 +5005,7 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn,
       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)
        {
@@ -5925,8 +5925,9 @@ remove_inheritance_pseudos (bitmap remove_pseudos)
                    {
                      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
@@ -6049,9 +6050,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 25bd3ce..e1d5ef2 100644 (file)
@@ -358,8 +358,8 @@ extern void lra_update_dups (lra_insn_recog_data_t, signed char *);
 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 5157c85..88c0ef6 100644 (file)
@@ -726,7 +726,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
                    {
                      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 5d1f429..bdd8e3c 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -1777,9 +1777,10 @@ lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after,
 \f
 
 /* 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;
@@ -1791,9 +1792,25 @@ lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg)
     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
@@ -1815,26 +1832,30 @@ lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg)
     {
       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);
 }
 
 \f
index 33877d4..4f09154 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-30  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR debug/66691
+       * gcc.target/i386/pr66691.c: New.
+
 2015-06-30  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gcc.target/i386/iamcu/abi-iamcu.exp: New file.