summaryrefslogtreecommitdiff
path: root/gcc/ifcvt.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>2000-04-30 23:55:44 -0700
committerRichard Henderson <rth@gcc.gnu.org>2000-04-30 23:55:44 -0700
commitc4686982aaf87c31ecb76bb361ec3a6685913e4b (patch)
tree39852d20e67e689559350a4521e3abf6099689cc /gcc/ifcvt.c
parent5724a0e6410d5f68761acc1ba338cce11d3677c8 (diff)
downloadgcc-c4686982aaf87c31ecb76bb361ec3a6685913e4b.tar.gz
ifcvt.c (noce_process_if_block): Fail the conversion if X is referenced bewteen the condition and the jump.
* ifcvt.c (noce_process_if_block): Fail the conversion if X is referenced bewteen the condition and the jump. Don't delete anything but the jump. From-SVN: r33563
Diffstat (limited to 'gcc/ifcvt.c')
-rw-r--r--gcc/ifcvt.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index b831b3e14d2..ba310da9d84 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -1024,7 +1024,7 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb)
rtx insn_a, insn_b;
rtx set_a, set_b;
rtx orig_x, x, a, b;
- rtx jump, cond;
+ rtx jump, cond, insn;
/* If this is not a standard conditional jump, we can't parse it. */
jump = test_bb->end;
@@ -1046,6 +1046,11 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb)
x = SET_DEST (set_a);
a = SET_SRC (set_a);
+ /* X may not be mentioned between cond_earliest and the jump. */
+ for (insn = jump; insn != if_info.cond_earliest; insn = PREV_INSN (insn))
+ if (INSN_P (insn) && reg_mentioned_p (x, insn))
+ return FALSE;
+
/* Look for the other potential set. Make sure we've got equivalent
destinations. */
/* ??? This is overconservative. Storing to two different mems is
@@ -1165,10 +1170,10 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb)
}
/* The new insns will have been inserted before cond_earliest. We should
- be able to remove cond_earliest through the jump with impunity. */
- insn_a = prev_nonnote_insn (if_info.cond_earliest);
- flow_delete_insn_chain (if_info.cond_earliest, test_bb->end);
- test_bb->end = insn_a;
+ be able to remove the jump with impunity, but the condition itself may
+ have been modified by gcse to be shared across basic blocks. */
+ test_bb->end = PREV_INSN (jump);
+ flow_delete_insn (jump);
/* If we used a temporary, fix it up now. */
if (orig_x != x)
@@ -1178,7 +1183,7 @@ noce_process_if_block (test_bb, then_bb, else_bb, join_bb)
insn_b = gen_sequence ();
end_sequence ();
- test_bb->end = emit_insn_after (insn_b, insn_a);
+ test_bb->end = emit_insn_after (insn_b, test_bb->end);
}
/* Merge the blocks! */