From a39fe6879370cf141c97292a496d7dae7705778b Mon Sep 17 00:00:00 2001 From: bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue, 14 Nov 2006 08:46:26 +0000 Subject: [PATCH] 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 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 | 9 +++++ gcc/fwprop.c | 39 +++++++++---------- gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.c-torture/execute/pr29798.c | 26 +++++++++++++ 4 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr29798.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 69f6627cf684..d1f36dfa6b7f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 1e4f749eb122..fb601e1a4f00 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -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 ()); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 370620b3cbbb..9693e4da1aaf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 000000000000..f7b90da02000 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr29798.c @@ -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; +} -- GitLab