OSDN Git Service

* ifcvt.c (noce_process_if_block): Correctly detect X modified
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Sep 2002 01:07:10 +0000 (01:07 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Sep 2002 01:07:10 +0000 (01:07 +0000)
        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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57294 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ifcvt.c
gcc/testsuite/gcc.c-torture/execute/20020916-1.c [new file with mode: 0644]

index 3a4be4e..40f48b7 100644 (file)
@@ -1,5 +1,12 @@
 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;
        always adjust parm_align for downward padding.
 
index 3ae828b..42c5fb5 100644 (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;
        }
 
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 (file)
index 0000000..3f2db15
--- /dev/null
@@ -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;
+}
+