Commit 6e0b633f by Paolo Bonzini Committed by Paolo Bonzini

re PR rtl-optimization/29798 (-O2 gives wrong results)

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.

From-SVN: r118808
parent b7e85170
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> 2006-11-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* fold-const.c (fold_strip_sign_ops): Handle COMPOUND_EXPR and * fold-const.c (fold_strip_sign_ops): Handle COMPOUND_EXPR and
......
...@@ -466,33 +466,32 @@ local_ref_killed_between_p (struct df_ref * ref, rtx from, rtx to) ...@@ -466,33 +466,32 @@ local_ref_killed_between_p (struct df_ref * ref, rtx from, rtx to)
static bool static bool
use_killed_between (struct df_ref *use, rtx def_insn, rtx target_insn) 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; int regno;
struct df_ref * def; struct df_ref * def;
/* 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);
def = DF_REG_DEF_GET (df, regno)->reg_chain;
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);
if (def_bb == target_bb)
{
/* In some obscure situations we can have a def reaching a use /* In some obscure situations we can have a def reaching a use
that is _before_ the def. In other words the def does not 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 dominate the use even though the use and def are in the same
basic block. This can happen when a register may be used basic block. This can happen when a register may be used
uninitialized in a loop. In such cases, we must assume that uninitialized in a loop. In such cases, we must assume that
DEF is not available. */ DEF is not available. */
if (DF_INSN_LUID (df, def_insn) >= DF_INSN_LUID (df, target_insn)) 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; 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);
def = DF_REG_DEF_GET (df, regno)->reg_chain;
if (def && (def->next_reg == NULL))
return false;
/* Check locally if we are in the same basic block. */
if (def_bb == target_bb)
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. */ /* Finally, if DEF_BB is the sole predecessor of TARGET_BB. */
if (single_pred_p (target_bb) if (single_pred_p (target_bb)
...@@ -890,16 +889,14 @@ static void ...@@ -890,16 +889,14 @@ static void
fwprop_init (void) fwprop_init (void)
{ {
num_changes = 0; num_changes = 0;
calculate_dominance_info (CDI_DOMINATORS);
/* We do not always want to propagate into loops, so we have to find /* 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 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 before df_analyze, because flow_loops_find may introduce new jump
insns (sadly) if we are not working in cfglayout mode. */ insns (sadly) if we are not working in cfglayout mode. */
if (flag_rerun_cse_after_loop && (flag_unroll_loops || flag_peel_loops)) 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 /* Now set up the dataflow problem (we only want use-def chains) and
put the dataflow solver to work. */ put the dataflow solver to work. */
...@@ -917,10 +914,10 @@ fwprop_done (void) ...@@ -917,10 +914,10 @@ fwprop_done (void)
if (flag_rerun_cse_after_loop && (flag_unroll_loops || flag_peel_loops)) if (flag_rerun_cse_after_loop && (flag_unroll_loops || flag_peel_loops))
{ {
flow_loops_free (&loops); flow_loops_free (&loops);
free_dominance_info (CDI_DOMINATORS);
loops.num = 0; loops.num = 0;
} }
free_dominance_info (CDI_DOMINATORS);
cleanup_cfg (0); cleanup_cfg (0);
delete_trivially_dead_insns (get_insns (), max_reg_num ()); delete_trivially_dead_insns (get_insns (), max_reg_num ());
......
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> 2006-11-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/builtins-20.c: Add more cases. * gcc.dg/builtins-20.c: Add more cases.
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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment