re PR debug/45849 (ICE: in emit_note_insn_var_location, at var-tracking.c:7336 with...
authorJakub Jelinek <jakub@redhat.com>
Mon, 4 Oct 2010 22:02:28 +0000 (00:02 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 4 Oct 2010 22:02:28 +0000 (00:02 +0200)
PR debug/45849
* var-tracking.c (strip_pointer_flags): New function.
(emit_note_insn_var_location): If rtx_equal_p check failed,
retry on locations simplified with simplify_replace_fn_rtx
and strip_pointer_flags as its callback.

* gcc.dg/debug/pr45849.c: New test.

From-SVN: r164962

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/debug/pr45849.c [new file with mode: 0644]
gcc/var-tracking.c

index 4511232..a949d2e 100644 (file)
@@ -1,3 +1,11 @@
+2010-10-04  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/45849
+       * var-tracking.c (strip_pointer_flags): New function.
+       (emit_note_insn_var_location): If rtx_equal_p check failed,
+       retry on locations simplified with simplify_replace_fn_rtx
+       and strip_pointer_flags as its callback.
+
 2010-10-04  Jan Hubicka  <jh@suse.cz>
 
        * gimple-fold.c (static_object_in_other_unit_p): Rename to...
index a8f6aae..1a21e0e 100644 (file)
@@ -1,5 +1,8 @@
 2010-10-04  Jakub Jelinek  <jakub@redhat.com>
 
+       PR debug/45849
+       * gcc.dg/debug/pr45849.c: New test.
+
        PR middle-end/45876
        * gcc.c-torture/compile/pr45876.c: New test.
 
diff --git a/gcc/testsuite/gcc.dg/debug/pr45849.c b/gcc/testsuite/gcc.dg/debug/pr45849.c
new file mode 100644 (file)
index 0000000..93279b7
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR debug/45849 */
+/* { dg-do compile } */
+/* { dg-options "-g -Wno-uninitialized" } */
+
+extern void bar (void);
+
+void
+foo (long repllen, char *rp)
+{
+  char *matchend;
+  char *scan;
+  long len;
+  char *matchstart;
+  char *text;
+  char *t;
+
+  repllen--;
+
+  for (;;)
+    {
+      matchstart = t + rp[0];
+      matchend = rp;
+      len = matchstart - text + repllen * (matchend - matchstart);
+      while (len)
+       ;
+      for (scan = text; scan != rp; scan++)
+       bar ();
+      if (matchstart)
+       text = matchend;
+    }
+}
index ec402ac..c74ef7c 100644 (file)
@@ -7133,6 +7133,19 @@ vt_expand_loc_dummy (rtx loc, htab_t vars, bool *pcur_loc_changed)
 #ifdef ENABLE_RTL_CHECKING
 /* Used to verify that cur_loc_changed updating is safe.  */
 static struct pointer_map_t *emitted_notes;
+
+/* Strip REG_POINTER from REGs and MEM_POINTER from MEMs in order to
+   avoid differences in commutative operand simplification.  */
+static rtx
+strip_pointer_flags (rtx x, const_rtx old_rtx ATTRIBUTE_UNUSED,
+                    void *data ATTRIBUTE_UNUSED)
+{
+  if (REG_P (x) && REG_POINTER (x))
+    return gen_rtx_REG (GET_MODE (x), REGNO (x));
+  if (MEM_P (x) && MEM_POINTER (x))
+    return gen_rtx_MEM (GET_MODE (x), XEXP (x, 0));
+  return NULL_RTX;
+}
 #endif
 
 /* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
@@ -7331,9 +7344,22 @@ emit_note_insn_var_location (void **varp, void *data)
       rtx pnote = (rtx) *note_slot;
       if (!var->cur_loc_changed && (pnote || PAT_VAR_LOCATION_LOC (note_vl)))
        {
+         rtx old_vl, new_vl;
          gcc_assert (pnote);
-         gcc_assert (rtx_equal_p (PAT_VAR_LOCATION_LOC (pnote),
-                                  PAT_VAR_LOCATION_LOC (note_vl)));
+         old_vl = PAT_VAR_LOCATION_LOC (pnote);
+         new_vl = PAT_VAR_LOCATION_LOC (note_vl);
+         if (!rtx_equal_p (old_vl, new_vl))
+           {
+             /* There might be differences caused by REG_POINTER
+                differences.  REG_POINTER affects
+                swap_commutative_operands_p.  */
+             old_vl = simplify_replace_fn_rtx (old_vl, NULL_RTX,
+                                               strip_pointer_flags, NULL);
+             new_vl = simplify_replace_fn_rtx (new_vl, NULL_RTX,
+                                               strip_pointer_flags, NULL);
+             gcc_assert (rtx_equal_p (old_vl, new_vl));
+             PAT_VAR_LOCATION_LOC (note_vl) = new_vl;
+           }
        }
       *note_slot = (void *) note_vl;
     }