re PR rtl-optimization/51187 (miscompilation of genrecog.c at -O2 for --target=avr)
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 19 Nov 2011 20:36:43 +0000 (20:36 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 19 Nov 2011 20:36:43 +0000 (20:36 +0000)
PR rtl-optimization/51187
* reorg.c (relax_delay_slots): Do not consider a jump useless if there
is a barrier between the jump and its target label.

From-SVN: r181513

gcc/ChangeLog
gcc/reorg.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/delay-slot-2.c [new file with mode: 0644]

index eb4e212..6f98784 100644 (file)
@@ -1,3 +1,9 @@
+2011-11-19  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR rtl-optimization/51187
+       * reorg.c (relax_delay_slots): Do not consider a jump useless if there
+       is a barrier between the jump and its target label.
+
 2011-11-19  Patrick Marlier  <patrick.marlier@gmail.com>
 
        PR middle-end/51211
index 40d73a7..0b90550 100644 (file)
@@ -3600,9 +3600,11 @@ relax_delay_slots (rtx first)
            }
        }
 
+      /* See if we have a simple (conditional) jump that is useless.  */
       if (! INSN_ANNULLED_BRANCH_P (delay_insn)
-         && prev_active_insn (target_label) == insn
          && ! condjump_in_parallel_p (delay_insn)
+         && prev_active_insn (target_label) == insn
+         && ! BARRIER_P (prev_nonnote_insn (target_label))
 #ifdef HAVE_cc0
          /* If the last insn in the delay slot sets CC0 for some insn,
             various code assumes that it is in a delay slot.  We could
index d4e8dfb..5b579e0 100644 (file)
@@ -1,3 +1,7 @@
+2011-11-19  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.dg/delay-slot-2.c: New test.
+
 2011-11-18  Joseph Myers  <joseph@codesourcery.com>
 
        * gcc.dg/cpp/assert4.c: Test __linux__, not __gnu_linux__.
diff --git a/gcc/testsuite/gcc.dg/delay-slot-2.c b/gcc/testsuite/gcc.dg/delay-slot-2.c
new file mode 100644 (file)
index 0000000..79faf81
--- /dev/null
@@ -0,0 +1,116 @@
+/* PR rtl-optimization/51187 */
+/* Reported by Jurij Smakov <jurij@wooyd.org> */
+
+/* { dg-do compile } */
+/* { dg-options "-g -O2" } */
+
+extern int printf (__const char *__restrict __format, ...);
+extern void print_c_condition (const char *);
+
+enum decision_type
+{
+  DT_num_insns,
+  DT_mode, DT_code, DT_veclen,
+  DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide, DT_elt_zero_wide_safe,
+  DT_const_int,
+  DT_veclen_ge, DT_dup, DT_pred, DT_c_test,
+  DT_accept_op, DT_accept_insn
+};
+
+struct decision_test
+{
+  struct decision_test *next;
+  enum decision_type type;
+
+  union
+  {
+    int num_insns;
+
+    struct
+    {
+      const char *name;
+    } pred;
+
+    const char *c_test;
+    int veclen;
+    int dup;
+    long intval;
+    int opno;
+
+    struct {
+      int code_number;
+      int lineno;
+      int num_clobbers_to_add;
+    } insn;
+  } u;
+};
+
+enum routine_type {
+  RECOG, SPLIT, PEEPHOLE2
+};
+
+void
+write_cond (struct decision_test *p, int depth,
+     enum routine_type subroutine_type)
+{
+  switch (p->type)
+    {
+    case DT_num_insns:
+      printf ("peep2_current_count >= %d", p->u.num_insns);
+      break;
+
+    case DT_code:
+      printf ("GET_CODE (x%d) == ", depth);
+      break;
+
+    case DT_veclen:
+      printf ("XVECLEN (x%d, 0) == %d", depth, p->u.veclen);
+      break;
+
+    case DT_elt_zero_int:
+      printf ("XINT (x%d, 0) == %d", depth, (int) p->u.intval);
+      break;
+
+    case DT_elt_one_int:
+      printf ("XINT (x%d, 1) == %d", depth, (int) p->u.intval);
+      break;
+
+    case DT_elt_zero_wide:
+    case DT_elt_zero_wide_safe:
+      printf ("XWINT (x%d, 0) == ", depth);
+      print_host_wide_int (p->u.intval);
+      break;
+
+    case DT_const_int:
+      printf ("x%d == const_int_rtx[MAX_SAVED_CONST_INT + (%d)]",
+       depth, (int) p->u.intval);
+      break;
+
+    case DT_veclen_ge:
+      printf ("XVECLEN (x%d, 0) >= %d", depth, p->u.veclen);
+      break;
+
+    case DT_dup:
+      printf ("rtx_equal_p (x%d, operands[%d])", depth, p->u.dup);
+      break;
+
+    case DT_pred:
+      printf ("%s (x%d)", p->u.pred.name, depth);
+      break;
+
+    case DT_c_test:
+      print_c_condition (p->u.c_test);
+      break;
+
+    case DT_accept_insn:
+      ((void)(__builtin_expect(!(subroutine_type == RECOG), 0) ? __builtin_unreachable(), 0 : 0));
+      ((void)(__builtin_expect(!(p->u.insn.num_clobbers_to_add), 0) ? __builtin_unreachable(), 0 : 0));
+      printf ("pnum_clobbers != NULL");
+      break;
+
+    default:
+      __builtin_unreachable();
+    }
+}
+
+/* { dg-final { scan-assembler "printf" } } */