From bf3d27e6892e4438d183062340ce17e39cb9fa9d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 18 Sep 2002 18:07:10 -0700 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 +++++ gcc/ifcvt.c | 30 ++++++------------- .../gcc.c-torture/execute/20020916-1.c | 19 ++++++++++++ 3 files changed, 35 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20020916-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3a4be4e6d2d..40f48b7fa15 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2002-09-18 Richard Henderson + + * 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 * calls.c (store_one_arg): Rename default_align to parm_align; diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 3ae828b43f8..42c5fb50bdb 100644 --- a/gcc/ifcvt.c +++ b/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; } diff --git a/gcc/testsuite/gcc.c-torture/execute/20020916-1.c b/gcc/testsuite/gcc.c-torture/execute/20020916-1.c new file mode 100644 index 00000000000..3f2db15d019 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20020916-1.c @@ -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; +} + -- 2.30.2