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:
parent
1b1f20cab9
commit
bf3d27e689
3 changed files with 35 additions and 21 deletions
|
@ -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;
|
||||
|
|
30
gcc/ifcvt.c
30
gcc/ifcvt.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
19
gcc/testsuite/gcc.c-torture/execute/20020916-1.c
Normal file
19
gcc/testsuite/gcc.c-torture/execute/20020916-1.c
Normal 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;
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue