2006-11-14 Paolo Bonzini <bonzini@gnu.org>
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 Nov 2006 08:46:26 +0000 (08:46 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 Nov 2006 08:46:26 +0000 (08:46 +0000)
PR rtl-optimization/29798

* fwprop.c (use_killed_between): Check that DEF_INSN dominates
TARGET_INSN before any other check.
(fwprop_init): Always calculate dominators.
(fwprop_done): Always free them.

2006-11-14  Paolo Bonzini  <bonzini@gnu.org>

PR rtl-optimization/29798

* gcc.c-torture/execute/pr29798.c: New.

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

gcc/ChangeLog
gcc/fwprop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr29798.c [new file with mode: 0644]

index 69f6627..d1f36df 100644 (file)
@@ -1,3 +1,12 @@
+2006-11-14  Paolo Bonzini  <bonzini@gnu.org>
+
+       PR rtl-optimization/29798
+
+       * fwprop.c (use_killed_between): Check that DEF_INSN dominates
+       TARGET_INSN before any other check.
+       (fwprop_init): Always calculate dominators.
+       (fwprop_done): Always free them.
+
 2006-11-14  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * fold-const.c (fold_strip_sign_ops): Handle COMPOUND_EXPR and
index 1e4f749..fb601e1 100644 (file)
@@ -466,10 +466,22 @@ local_ref_killed_between_p (struct df_ref * ref, rtx from, rtx to)
 static bool
 use_killed_between (struct df_ref *use, rtx def_insn, rtx target_insn)
 {
-  basic_block def_bb, target_bb;
+  basic_block def_bb = BLOCK_FOR_INSN (def_insn);
+  basic_block target_bb = BLOCK_FOR_INSN (target_insn);
   int regno;
   struct df_ref * def;
 
+  /* In some obscure situations we can have a def reaching a use
+     that is _before_ the def.  In other words the def does not
+     dominate the use even though the use and def are in the same
+     basic block.  This can happen when a register may be used
+     uninitialized in a loop.  In such cases, we must assume that
+     DEF is not available.  */
+  if (def_bb == target_bb
+      ? DF_INSN_LUID (df, def_insn) >= DF_INSN_LUID (df, target_insn)
+      : !dominated_by_p (CDI_DOMINATORS, target_bb, def_bb))
+    return true;
+
   /* Check if the reg in USE has only one definition.  We already
      know that this definition reaches use, or we wouldn't be here.  */
   regno = DF_REF_REGNO (use);
@@ -477,22 +489,9 @@ use_killed_between (struct df_ref *use, rtx def_insn, rtx target_insn)
   if (def && (def->next_reg == NULL))
     return false;
 
-  /* Check if we are in the same basic block.  */
-  def_bb = BLOCK_FOR_INSN (def_insn);
-  target_bb = BLOCK_FOR_INSN (target_insn);
+  /* Check locally if we are in the same basic block.  */
   if (def_bb == target_bb)
-    {
-      /* In some obscure situations we can have a def reaching a use
-        that is _before_ the def.  In other words the def does not
-        dominate the use even though the use and def are in the same
-        basic block.  This can happen when a register may be used
-        uninitialized in a loop.  In such cases, we must assume that
-        DEF is not available.  */
-      if (DF_INSN_LUID (df, def_insn) >= DF_INSN_LUID (df, target_insn))
-       return true;
-
-      return local_ref_killed_between_p (use, def_insn, target_insn);
-    }
+    return local_ref_killed_between_p (use, def_insn, target_insn);
 
   /* Finally, if DEF_BB is the sole predecessor of TARGET_BB.  */
   if (single_pred_p (target_bb)
@@ -890,16 +889,14 @@ static void
 fwprop_init (void)
 {
   num_changes = 0;
+  calculate_dominance_info (CDI_DOMINATORS);
 
   /* We do not always want to propagate into loops, so we have to find
      loops and be careful about them.  But we have to call flow_loops_find
      before df_analyze, because flow_loops_find may introduce new jump
      insns (sadly) if we are not working in cfglayout mode.  */
   if (flag_rerun_cse_after_loop && (flag_unroll_loops || flag_peel_loops))
-    {
-      calculate_dominance_info (CDI_DOMINATORS);
-      flow_loops_find (&loops);
-    }
+    flow_loops_find (&loops);
 
   /* Now set up the dataflow problem (we only want use-def chains) and
      put the dataflow solver to work.  */
@@ -917,10 +914,10 @@ fwprop_done (void)
   if (flag_rerun_cse_after_loop && (flag_unroll_loops || flag_peel_loops))
     {
       flow_loops_free (&loops);
-      free_dominance_info (CDI_DOMINATORS);
       loops.num = 0;
     }
 
+  free_dominance_info (CDI_DOMINATORS);
   cleanup_cfg (0);
   delete_trivially_dead_insns (get_insns (), max_reg_num ());
 
index 370620b..9693e4d 100644 (file)
@@ -1,3 +1,9 @@
+2006-11-14  Paolo Bonzini  <bonzini@gnu.org>
+
+       PR rtl-optimization/29798
+
+       * gcc.c-torture/execute/pr29798.c: New.
+
 2006-11-14  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * gcc.dg/builtins-20.c: Add more cases.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr29798.c b/gcc/testsuite/gcc.c-torture/execute/pr29798.c
new file mode 100644 (file)
index 0000000..f7b90da
--- /dev/null
@@ -0,0 +1,26 @@
+extern void abort ();
+
+int
+main ()
+{
+  int i;
+  double oldrho;
+  double beta = 0.0;
+  double work = 1.0;
+  for (i = 1; i <= 2; i++)
+    {
+      double rho = work * work;
+      if (i != 1)
+        beta = rho / oldrho;
+      if (beta == 1.0)
+        abort ();
+
+      /* All targets even remotely likely to ever get supported
+        use at least an even base, so there will never be any
+        floating-point rounding. All computation in this test
+        case is exact for even bases.  */
+      work /= 2.0;
+      oldrho = rho;
+    }
+  return 0;
+}