From: Jason Merrill Date: Tue, 25 Mar 2003 20:24:42 +0000 (-0500) Subject: re PR rtl-optimization/10171 (wrong code for inlined function) X-Git-Tag: releases/gcc-3.4.0~7664 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e2255ffff45da118ea54715fbe880624f29b9cf;p=thirdparty%2Fgcc.git re PR rtl-optimization/10171 (wrong code for inlined function) PR optimization/10171 * unroll.c (unroll_loop): Don't delete the jump at the end unless we also delete a jump at the beginning. From-SVN: r64863 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5f7edc74e80..791d08cbf651 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2003-03-21 Jason Merrill + + PR optimization/10171 + * unroll.c (unroll_loop): Don't delete the jump at the end unless + we also delete a jump at the beginning. + 2003-03-25 Stephane Carrez * doc/contrib.texi (Contributors): Mention self as 68HC11/68HC12 diff --git a/gcc/testsuite/gcc.dg/loop-2.c b/gcc/testsuite/gcc.dg/loop-2.c new file mode 100644 index 000000000000..e939f327bacf --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-2.c @@ -0,0 +1,20 @@ +/* PR optimization/10171 */ +/* Bug: unroll_loop misoptimized the function so that we got + 0 iterations of the loop rather than the correct 1. */ +/* { dg-do run } */ + +inline int tag() { return 0; } + +void f (); + +int main() { + int i; + for (i = 0; i < (tag() ? 2 : 1); i++) + f(); + abort (); +} + +void f () +{ + exit (0); +} diff --git a/gcc/unroll.c b/gcc/unroll.c index 3b5dd7c91f8c..9db997512c1a 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -305,9 +305,11 @@ unroll_loop (loop, insn_count, strength_reduce_p) jump to the loop condition. Make sure to delete the jump insn, otherwise the loop body will never execute. */ + /* FIXME this actually checks for a jump to the continue point, which + is not the same as the condition in a for loop. As a result, this + optimization fails for most for loops. We should really use flow + information rather than instruction pattern matching. */ rtx ujump = ujump_to_loop_cont (loop->start, loop->cont); - if (ujump) - delete_related_insns (ujump); /* If number of iterations is exactly 1, then eliminate the compare and branch at the end of the loop since they will never be taken. @@ -319,9 +321,10 @@ unroll_loop (loop, insn_count, strength_reduce_p) if (GET_CODE (last_loop_insn) == BARRIER) { /* Delete the jump insn. This will delete the barrier also. */ - delete_related_insns (PREV_INSN (last_loop_insn)); + last_loop_insn = PREV_INSN (last_loop_insn); } - else if (GET_CODE (last_loop_insn) == JUMP_INSN) + + if (ujump && GET_CODE (last_loop_insn) == JUMP_INSN) { #ifdef HAVE_cc0 rtx prev = PREV_INSN (last_loop_insn); @@ -333,24 +336,27 @@ unroll_loop (loop, insn_count, strength_reduce_p) if (only_sets_cc0_p (prev)) delete_related_insns (prev); #endif - } - /* Remove the loop notes since this is no longer a loop. */ - if (loop->vtop) - delete_related_insns (loop->vtop); - if (loop->cont) - delete_related_insns (loop->cont); - if (loop_start) - delete_related_insns (loop_start); - if (loop_end) - delete_related_insns (loop_end); + delete_related_insns (ujump); - return; + /* Remove the loop notes since this is no longer a loop. */ + if (loop->vtop) + delete_related_insns (loop->vtop); + if (loop->cont) + delete_related_insns (loop->cont); + if (loop_start) + delete_related_insns (loop_start); + if (loop_end) + delete_related_insns (loop_end); + + return; + } } - else if (loop_info->n_iterations > 0 - /* Avoid overflow in the next expression. */ - && loop_info->n_iterations < (unsigned) MAX_UNROLLED_INSNS - && loop_info->n_iterations * insn_count < (unsigned) MAX_UNROLLED_INSNS) + + if (loop_info->n_iterations > 0 + /* Avoid overflow in the next expression. */ + && loop_info->n_iterations < (unsigned) MAX_UNROLLED_INSNS + && loop_info->n_iterations * insn_count < (unsigned) MAX_UNROLLED_INSNS) { unroll_number = loop_info->n_iterations; unroll_type = UNROLL_COMPLETELY;