re PR rtl-optimization/53701 (ICE on ia64 (when building Allegro 4.4) in sel-sched)
authorAndrey Belevantsev <abel@ispras.ru>
Thu, 9 Aug 2012 14:08:31 +0000 (18:08 +0400)
committerAndrey Belevantsev <abel@gcc.gnu.org>
Thu, 9 Aug 2012 14:08:31 +0000 (18:08 +0400)
    PR rtl-optimization/53701
    * sel-sched.c (vinsn_vec_has_expr_p): Clarify function comment.
    Process not only expr's vinsns but all old vinsns from expr's
    history of changes.
    (update_and_record_unavailable_insns): Clarify comment.

    * gcc.dg/pr53701.c: New test.

From-SVN: r190253

gcc/ChangeLog
gcc/sel-sched.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr53701.c [new file with mode: 0644]

index 2a00c31eb00dc56abd2bd9929cad86c5052cadb9..618cba07e7152bbea88cb6bca1f377fe59413db4 100644 (file)
@@ -1,3 +1,11 @@
+2012-08-09  Andrey Belevantsev  <abel@ispras.ru>
+
+       PR rtl-optimization/53701
+       * sel-sched.c (vinsn_vec_has_expr_p): Clarify function comment.
+       Process not only expr's vinsns but all old vinsns from expr's
+       history of changes.
+       (update_and_record_unavailable_insns): Clarify comment. 
+
 2012-08-09  Bernd Schmidt  <bernds@codesourcery.com>
 
        * reload.c (find_valid_class_1): New static function.
index 3099b92627a87ce00b0abe5d47ac0de54dcb45c5..f0c6eafb6f329000a433d5db2a533c514f8a98af 100644 (file)
@@ -3564,29 +3564,41 @@ process_use_exprs (av_set_t *av_ptr)
   return NULL;
 }
 
-/* Lookup EXPR in VINSN_VEC and return TRUE if found.  */
+/* Lookup EXPR in VINSN_VEC and return TRUE if found.  Also check patterns from
+   EXPR's history of changes.  */
 static bool
 vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr)
 {
-  vinsn_t vinsn;
+  vinsn_t vinsn, expr_vinsn;
   int n;
+  unsigned i;
 
-  FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn)
-    if (VINSN_SEPARABLE_P (vinsn))
-      {
-        if (vinsn_equal_p (vinsn, EXPR_VINSN (expr)))
-          return true;
-      }
-    else
-      {
-        /* For non-separable instructions, the blocking insn can have
-           another pattern due to substitution, and we can't choose
-           different register as in the above case.  Check all registers
-           being written instead.  */
-        if (bitmap_intersect_p (VINSN_REG_SETS (vinsn),
-                                VINSN_REG_SETS (EXPR_VINSN (expr))))
-          return true;
-      }
+  /* Start with checking expr itself and then proceed with all the old forms
+     of expr taken from its history vector.  */
+  for (i = 0, expr_vinsn = EXPR_VINSN (expr);
+       expr_vinsn;
+       expr_vinsn = (i < VEC_length (expr_history_def,
+                                    EXPR_HISTORY_OF_CHANGES (expr))
+                    ? VEC_index (expr_history_def,
+                                 EXPR_HISTORY_OF_CHANGES (expr),
+                                 i++)->old_expr_vinsn
+                    : NULL))
+    FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn)
+      if (VINSN_SEPARABLE_P (vinsn))
+       {
+         if (vinsn_equal_p (vinsn, expr_vinsn))
+           return true;
+       }
+      else
+       {
+         /* For non-separable instructions, the blocking insn can have
+            another pattern due to substitution, and we can't choose
+            different register as in the above case.  Check all registers
+            being written instead.  */
+         if (bitmap_intersect_p (VINSN_REG_SETS (vinsn),
+                                 VINSN_REG_SETS (expr_vinsn)))
+           return true;
+       }
 
   return false;
 }
@@ -5694,8 +5706,8 @@ update_and_record_unavailable_insns (basic_block book_block)
               || EXPR_TARGET_AVAILABLE (new_expr)
                 != EXPR_TARGET_AVAILABLE (cur_expr))
            /* Unfortunately, the below code could be also fired up on
-              separable insns.
-              FIXME: add an example of how this could happen.  */
+              separable insns, e.g. when moving insns through the new
+              speculation check as in PR 53701.  */
             vinsn_vec_add (&vec_bookkeeping_blocked_vinsns, cur_expr);
         }
 
index 7dcf7d760edc0954aa62012057d2db38c6c15411..1ac24cdb0b81f6fbc5f7a7871abe5ff7a7e68c10 100644 (file)
@@ -1,3 +1,8 @@
+2012-08-09  Andrey Belevantsev  <abel@ispras.ru>
+
+       PR rtl-optimization/53701
+       * gcc.dg/pr53701.c: New test. 
+
 2012-08-09  Bernd Schmidt  <bernds@codesourcery.com>
 
        * gcc.c-torture/compile/20120727-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr53701.c b/gcc/testsuite/gcc.dg/pr53701.c
new file mode 100644 (file)
index 0000000..2c85223
--- /dev/null
@@ -0,0 +1,59 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O3 -fselective-scheduling2 -fsel-sched-pipelining" } */
+typedef unsigned short int uint16_t;
+typedef unsigned long int uintptr_t;
+typedef struct GFX_VTABLE
+{
+  int color_depth;
+  unsigned char *line[];
+}
+BITMAP;
+extern int _drawing_mode;
+extern BITMAP *_drawing_pattern;
+extern int _drawing_y_anchor;
+extern unsigned int _drawing_x_mask;
+extern unsigned int _drawing_y_mask;
+extern uintptr_t bmp_write_line (BITMAP *, int);
+  void
+_linear_hline15 (BITMAP * dst, int dx1, int dy, int dx2, int color)
+{
+  int w;
+  if (_drawing_mode == 0)
+  {
+    int x, curw;
+    unsigned short *sline =
+      (unsigned short *) (_drawing_pattern->
+          line[((dy) -
+            _drawing_y_anchor) & _drawing_y_mask]);
+    unsigned short *s;
+    unsigned short *d =
+      ((unsigned short *) (bmp_write_line (dst, dy)) + (dx1));
+    s = ((unsigned short *) (sline) + (x));
+    if (_drawing_mode == 2)
+    {
+    }
+    else if (_drawing_mode == 3)
+    {
+      do
+      {
+        w -= curw;
+        do
+        {
+          unsigned long c = (*(s));
+          if (!((unsigned long) (c) == 0x7C1F))
+          {
+            (*((uint16_t *) ((uintptr_t) (d))) = ((color)));
+          }
+          ((s)++);
+        }
+        while (--curw > 0);
+        s = sline;
+        curw =
+          (((w) <
+            ((int) _drawing_x_mask +
+             1)) ? (w) : ((int) _drawing_x_mask + 1));
+      }
+      while (curw > 0);
+    }
+  }
+}