diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0715f74e6848..576a7d16ab46 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-08-14 Andrey Belevantsev + + PR rtl-optimization/57662 + * sel-sched.c (code_motion_process_successors): When the current insn + is removed after the recursive traversal, break from the loop. + Add comments and debug printouts. + 2013-08-14 Jakub Jelinek Alexandre Oliva diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index fb9386f96900..46c66b4f3ed3 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -6424,10 +6424,23 @@ code_motion_process_successors (insn_t insn, av_set_t orig_ops, res = b; /* We have simplified the control flow below this point. In this case, - the iterator becomes invalid. We need to try again. */ + the iterator becomes invalid. We need to try again. + If we have removed the insn itself, it could be only an + unconditional jump. Thus, do not rescan but break immediately -- + we have already visited the only successor block. */ + if (!BLOCK_FOR_INSN (insn)) + { + if (sched_verbose >= 6) + sel_print ("Not doing rescan: already visited the only successor" + " of block %d\n", old_index); + break; + } if (BLOCK_FOR_INSN (insn)->index != old_index || EDGE_COUNT (bb->succs) != old_succs) { + if (sched_verbose >= 6) + sel_print ("Rescan: CFG was simplified below insn %d, block %d\n", + INSN_UID (insn), BLOCK_FOR_INSN (insn)->index); insn = sel_bb_end (BLOCK_FOR_INSN (insn)); goto rescan; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 75a1237ec653..7c4c070320df 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-08-14 Andrey Belevantsev + + PR rtl-optimization/57662 + * gcc.dg/pr57662.c: New test. + 2013-08-13 Maciej W. Rozycki * gcc.target/mips/nan-legacy.c: Accept 4294967295 as an diff --git a/gcc/testsuite/gcc.dg/pr57662.c b/gcc/testsuite/gcc.dg/pr57662.c new file mode 100644 index 000000000000..7af845532b8b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr57662.c @@ -0,0 +1,47 @@ +/* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */ +/* { dg-options " -O -fno-guess-branch-probability -fpeel-loops -freorder-blocks-and-partition -fschedule-insns2 -fsel-sched-pipelining -fselective-scheduling2 -ftree-pre" } */ + +struct intC +{ + short x; + short y; +}; + +void Get(void); + +int size_x; + +struct +{ + int *depot_table; + struct intC *ti; + int size; +} dummy; + +static inline int +GetRotatedTileFromOffset (int *a, struct intC tidc) +{ + if (!*a) + Get (); + switch (*a) + { + case 0: + return (tidc.y << size_x) + tidc.x; + case 1: + return tidc.y + (dummy.size - tidc.x) * size_x; + case 2: + return tidc.x + (dummy.size - tidc.y) * size_x; + case 3: + return (dummy.size - tidc.x); + } + return 0; +} + +int +GetHangarNum (int *a, int i) +{ + while (dummy.size) + if (GetRotatedTileFromOffset (a, dummy.ti[i])) + return *dummy.depot_table; + return 0; +}