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:
parent
b7e85170cf
commit
6e0b633f6c
4 changed files with 59 additions and 21 deletions
|
@ -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
|
||||
|
|
39
gcc/fwprop.c
39
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 ());
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
26
gcc/testsuite/gcc.c-torture/execute/pr29798.c
Normal file
26
gcc/testsuite/gcc.c-torture/execute/pr29798.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue