ifcvt.c (noce_process_if_block): Correctly detect X modified with INSN_B before COND_EARLIEST.

* ifcvt.c (noce_process_if_block): Correctly detect X modified
        with INSN_B before COND_EARLIEST.  Don't check A and B for
        modification in condition range.  Reorder INSN_B for A==B properly.
        (if_convert): Iterate until no matches for a block.

	* gcc.c-torture/execute/20020916-1.c: New.

From-SVN: r57294
This commit is contained in:
Richard Henderson 2002-09-18 18:07:10 -07:00 committed by Richard Henderson
parent 1b1f20cab9
commit bf3d27e689
3 changed files with 35 additions and 21 deletions

View file

@ -1,3 +1,10 @@
2002-09-18 Richard Henderson <rth@redhat.com>
* ifcvt.c (noce_process_if_block): Correctly detect X modified
with INSN_B before COND_EARLIEST. Don't check A and B for
modification in condition range. Reorder INSN_B for A==B properly.
(if_convert): Iterate until no matches for a block.
2002-09-18 Richard Henderson <rth@redhat.com>
* calls.c (store_one_arg): Rename default_align to parm_align;

View file

@ -1700,7 +1700,7 @@ noce_process_if_block (ce_info)
rtx insn_a, insn_b;
rtx set_a, set_b;
rtx orig_x, x, a, b;
rtx jump, cond, insn;
rtx jump, cond;
/* We're looking for patterns of the form
@ -1776,24 +1776,12 @@ noce_process_if_block (ce_info)
|| ! rtx_equal_p (x, SET_DEST (set_b))
|| reg_overlap_mentioned_p (x, cond)
|| reg_overlap_mentioned_p (x, a)
|| reg_overlap_mentioned_p (x, SET_SRC (set_b)))
|| reg_overlap_mentioned_p (x, SET_SRC (set_b))
|| modified_between_p (x, if_info.cond_earliest, NEXT_INSN (jump)))
insn_b = set_b = NULL_RTX;
}
b = (set_b ? SET_SRC (set_b) : x);
/* X may not be mentioned in the range (cond_earliest, jump].
Note the use of reg_overlap_mentioned_p, which handles memories
properly, as opposed to reg_mentioned_p, which doesn't. */
for (insn = jump; insn != if_info.cond_earliest; insn = PREV_INSN (insn))
if (INSN_P (insn) && reg_overlap_mentioned_p (x, PATTERN (insn)))
return FALSE;
/* A and B may not be modified in the range [cond_earliest, jump). */
for (insn = if_info.cond_earliest; insn != jump; insn = NEXT_INSN (insn))
if (INSN_P (insn)
&& (modified_in_p (a, insn) || modified_in_p (b, insn)))
return FALSE;
/* Only operate on register destinations, and even then avoid extending
the lifetime of hard registers on small register class machines. */
orig_x = x;
@ -1839,7 +1827,7 @@ noce_process_if_block (ce_info)
if (else_bb && insn_b == else_bb->end)
else_bb->end = PREV_INSN (insn_b);
reorder_insns (insn_b, insn_b, PREV_INSN (if_info.cond_earliest));
reorder_insns (insn_b, insn_b, PREV_INSN (jump));
/* If there was a REG_EQUAL note, delete it since it may have been
true due to this insn being after a jump. */
@ -1894,9 +1882,9 @@ noce_process_if_block (ce_info)
if (insn_b && else_bb)
delete_insn (insn_b);
/* The new insns will have been inserted before cond_earliest. We should
be able to remove the jump with impunity, but the condition itself may
have been modified by gcse to be shared across basic blocks. */
/* The new insns will have been inserted immediately before the jump. We
should be able to remove the jump with impunity, but the condition itself
may have been modified by gcse to be shared across basic blocks. */
delete_insn (jump);
/* If we used a temporary, fix it up now. */
@ -3115,8 +3103,8 @@ if_convert (x_life_data_ok)
FOR_EACH_BB (bb)
{
basic_block new_bb = find_if_header (bb, pass);
if (new_bb)
basic_block new_bb;
while ((new_bb = find_if_header (bb, pass)))
bb = new_bb;
}

View file

@ -0,0 +1,19 @@
/* Distilled from try_pre_increment in flow.c. If-conversion inserted
new instructions at the wrong place on ppc. */
int foo(int a)
{
int x;
x = 0;
if (a > 0) x = 1;
if (a < 0) x = 1;
return x;
}
int main()
{
if (foo(1) != 1)
abort();
return 0;
}