diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2005-04-02 16:53:44 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2005-04-02 16:53:44 +0000 |
commit | 9f05ff0a19805354543881f05f84d3157e619bad (patch) | |
tree | 044b11cdff4c1f9ae9e84e8a7ad960da4a7111d2 /gcc/loop.c | |
parent | 3a5afdfc208747167216c3318134c159860b59b2 (diff) | |
download | gcc-9f05ff0a19805354543881f05f84d3157e619bad.zip gcc-9f05ff0a19805354543881f05f84d3157e619bad.tar.gz gcc-9f05ff0a19805354543881f05f84d3157e619bad.tar.bz2 |
re PR rtl-optimization/20290 (Miscompilation on ppc/arm with -Os)
gcc/ChangeLog:
PR rtl-optimization/20290
* loop.c (for_each_insn_in_loop): Don't assume the loop body runs
in every iteration if the entry point is the exit test.
gcc/testsuite/ChangeLog:
PR rtl-optimization/20290
* gcc.c-torture/execute/loop-ivopts-2.c: New.
From-SVN: r97441
Diffstat (limited to 'gcc/loop.c')
-rw-r--r-- | gcc/loop.c | 22 |
1 files changed, 15 insertions, 7 deletions
@@ -4654,12 +4654,18 @@ for_each_insn_in_loop (struct loop *loop, loop_insn_callback fncall) int not_every_iteration = 0; int maybe_multiple = 0; int past_loop_latch = 0; + bool exit_test_is_entry = false; rtx p; - /* If loop_scan_start points to the loop exit test, we have to be wary of - subversive use of gotos inside expression statements. */ + /* If loop_scan_start points to the loop exit test, the loop body + cannot be counted on running on every iteration, and we have to + be wary of subversive use of gotos inside expression + statements. */ if (prev_nonnote_insn (loop->scan_start) != prev_nonnote_insn (loop->start)) - maybe_multiple = back_branch_in_range_p (loop, loop->scan_start); + { + exit_test_is_entry = true; + maybe_multiple = back_branch_in_range_p (loop, loop->scan_start); + } /* Scan through loop and update NOT_EVERY_ITERATION and MAYBE_MULTIPLE. */ for (p = next_insn_in_loop (loop, loop->scan_start); @@ -4717,10 +4723,12 @@ for_each_insn_in_loop (struct loop *loop, loop_insn_callback fncall) beginning, don't set not_every_iteration for that. This can be any kind of jump, since we want to know if insns will be executed if the loop is executed. */ - && !(JUMP_LABEL (p) == loop->top - && ((NEXT_INSN (NEXT_INSN (p)) == loop->end - && any_uncondjump_p (p)) - || (NEXT_INSN (p) == loop->end && any_condjump_p (p))))) + && (exit_test_is_entry + || !(JUMP_LABEL (p) == loop->top + && ((NEXT_INSN (NEXT_INSN (p)) == loop->end + && any_uncondjump_p (p)) + || (NEXT_INSN (p) == loop->end + && any_condjump_p (p)))))) { rtx label = 0; |