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
This commit is contained in:
Paolo Bonzini 2006-11-14 08:46:26 +00:00 committed by Paolo Bonzini
parent b7e85170cf
commit 6e0b633f6c
4 changed files with 59 additions and 21 deletions

View 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

View 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 ());

View 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.

View file

@ -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;
}