This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Patch: add missing if-then-else optimization
The scan for a modification of X was incorrect; reg_overlap_mentioned_p
didn't do what I thought it did. In addition, we don't need to abort the
entire if-conversion -- we can still do the right thing by considering
B = X and use a conditional move.
Testing underway for alpha and i686.
r~
* ifcvt.c (noce_process_if_block): Correct X modified test when
no else block. Remove A/B modified check wrt cond_earliest.
(if_convert): Repeat find_if_header until no successes.
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.104
diff -c -p -d -u -r1.104 ifcvt.c
--- ifcvt.c 8 Sep 2002 12:47:26 -0000 1.104
+++ ifcvt.c 17 Sep 2002 06:53:39 -0000
@@ -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;
@@ -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;
}
Index: testsuite/gcc.c-torture/execute/20020916-1.c
===================================================================
RCS file: testsuite/gcc.c-torture/execute/20020916-1.c
diff -N testsuite/gcc.c-torture/execute/20020916-1.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/execute/20020916-1.c 17 Sep 2002 06:53:42 -0000
@@ -0,0 +1,15 @@
+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;
+}