re PR tree-optimization/23234 (ICE in verify_flow_info())

gcc/
	PR tree-optimization/23234
	* tree-ssa-math-opts.c (place_reciprocal): New enum.
	(execute_cse_reciprocals_1): Replace the 'phi' argument with an
	argument of the new enum.
	(execute_cse_reciprocals): Add reciprocals for function arguments
	on the unique successor edge of the entry block.  Update other calls
	to execute_cse_reciprocals_1.

testsuite/
	PR tree-optimization/23234
	* gcc.dg/tree-ssa/pr23234.c: New test.

From-SVN: r102895
This commit is contained in:
Steven Bosscher 2005-08-09 03:28:38 +00:00
parent 3d092c45bf
commit 2ef571e2c2
4 changed files with 93 additions and 9 deletions

View File

@ -1,3 +1,13 @@
2005-08-09 Steven Bosscher <stevenb@suse.de>
PR tree-optimization/23234
* tree-ssa-math-opts.c (place_reciprocal): New enum.
(execute_cse_reciprocals_1): Replace the 'phi' argument with an
argument of the new enum.
(execute_cse_reciprocals): Add reciprocals for function arguments
on the unique successor edge of the entry block. Update other calls
to execute_cse_reciprocals_1.
2005-08-08 Richard Henderson <rth@redhat.com>
PR 22439

View File

@ -1,3 +1,8 @@
2005-08-09 Stevem Bosscher <stevenb@suse.de>
PR tree-optimization/23234
* gcc.dg/tree-ssa/pr23234.c: New test.
2005-08-08 Josh Conner <jconner@apple.com>
PR rtl-optimization/23241

View File

@ -0,0 +1,52 @@
/* The problem in this PR was mostly finding a suitable place to insert
the reciprocals of the function arguments. This test case tries to
test three possible ways of how this may go wrong. */
/* { dg-options "-O2 -ffast-math" } */
/* { dg-do compile } */
/* The original test case. */
double
f1 (double a, double b, double c)
{
double y0;
if (a == 0.0)
{
y0 = -c / b;
return y0;
}
y0 = c / b;
return y0;
}
/* Labels may end up in the middle of a block. Also bad. */
double
f2 (double a, double b, double c)
{
double y0;
a_label:
another_label:
if (a == 0.0)
{
y0 = -c / b;
return y0;
}
y0 = c / b;
return y0;
}
/* Uses must still be dominated by their defs. */
double
f3 (double a, double b, double c)
{
double y0;
y0 = -c / b;
if (a == 0.0)
{
return y0;
}
y0 = c / b;
return y0;
}

View File

@ -54,16 +54,25 @@ gate_cse_reciprocals (void)
return optimize && !optimize_size && flag_unsafe_math_optimizations;
}
/* Where to put the statement computing a reciprocal. */
enum place_reciprocal
{
PR_BEFORE_BSI, /* Put it using bsi_insert_before. */
PR_AFTER_BSI, /* Put it using bsi_insert_after. */
PR_ON_ENTRY_EDGE /* Put it on the edge between the entry
and the first basic block. */
};
/* Check if DEF's uses include more than one floating-point division,
and if so replace them by multiplications with the reciprocal. If
PHI is true, insert the reciprocal calculation before BSI, otherwise
insert it after and move BSI to the new statement.
and if so replace them by multiplications with the reciprocal. Add
the statement computing the reciprocal according to WHERE.
Does not check the type of DEF, nor that DEF is a GIMPLE register.
This is done in the caller for speed, because otherwise this routine
would be called for every definition and phi node. */
static void
execute_cse_reciprocals_1 (block_stmt_iterator *bsi, tree def, bool phi)
execute_cse_reciprocals_1 (block_stmt_iterator *bsi, tree def,
enum place_reciprocal where)
{
use_operand_p use_p;
imm_use_iterator use_iter;
@ -99,10 +108,14 @@ execute_cse_reciprocals_1 (block_stmt_iterator *bsi, tree def, bool phi)
fold_build2 (RDIV_EXPR, type, build_real (type, dconst1),
def));
if (phi)
if (where == PR_BEFORE_BSI)
bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
else
else if (where == PR_AFTER_BSI)
bsi_insert_after (bsi, new_stmt, BSI_NEW_STMT);
else if (where == PR_ON_ENTRY_EDGE)
bsi_insert_on_edge (single_succ_edge (ENTRY_BLOCK_PTR), new_stmt);
else
gcc_unreachable ();
FOR_EACH_IMM_USE_SAFE (use_p, use_iter, def)
{
@ -133,7 +146,8 @@ execute_cse_reciprocals (void)
{
block_stmt_iterator bsi;
bsi = bsi_start (single_succ (ENTRY_BLOCK_PTR));
execute_cse_reciprocals_1 (&bsi, default_def (arg), false);
execute_cse_reciprocals_1 (&bsi, default_def (arg),
PR_ON_ENTRY_EDGE);
}
FOR_EACH_BB (bb)
@ -150,7 +164,7 @@ execute_cse_reciprocals (void)
def = PHI_RESULT (phi);
if (FLOAT_TYPE_P (TREE_TYPE (def))
&& is_gimple_reg (def))
execute_cse_reciprocals_1 (&bsi, def, true);
execute_cse_reciprocals_1 (&bsi, def, PR_BEFORE_BSI);
}
for (; !bsi_end_p (bsi); bsi_next (&bsi))
@ -160,12 +174,15 @@ execute_cse_reciprocals (void)
&& (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL
&& FLOAT_TYPE_P (TREE_TYPE (def))
&& TREE_CODE (def) == SSA_NAME)
execute_cse_reciprocals_1 (&bsi, def, false);
execute_cse_reciprocals_1 (&bsi, def, PR_AFTER_BSI);
}
}
if (flag_trapping_math)
free_dominance_info (CDI_POST_DOMINATORS);
if (single_succ_p (ENTRY_BLOCK_PTR))
bsi_commit_one_edge_insert (single_succ_edge (ENTRY_BLOCK_PTR), NULL);
}
struct tree_opt_pass pass_cse_reciprocals =