From b168ced90319bca53a0057dabf9786cc341c6c43 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sat, 19 Nov 2011 20:36:43 +0000 Subject: [PATCH] re PR rtl-optimization/51187 (miscompilation of genrecog.c at -O2 for --target=avr) 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 | 6 ++ gcc/reorg.c | 4 +- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.dg/delay-slot-2.c | 116 ++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/delay-slot-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb4e2122b93..6f987847ce8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-11-19 Eric Botcazou + + 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 PR middle-end/51211 diff --git a/gcc/reorg.c b/gcc/reorg.c index 40d73a76a71..0b90550add5 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d4e8dfb17d5..5b579e0cd86 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-11-19 Eric Botcazou + + * gcc.dg/delay-slot-2.c: New test. + 2011-11-18 Joseph Myers * 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 index 00000000000..79faf81c798 --- /dev/null +++ b/gcc/testsuite/gcc.dg/delay-slot-2.c @@ -0,0 +1,116 @@ +/* PR rtl-optimization/51187 */ +/* Reported by Jurij Smakov */ + +/* { 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" } } */ -- 2.30.2