diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2005-08-09 03:28:38 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2005-08-09 03:28:38 +0000 |
commit | 2ef571e2c282999a7c3f46e6a0b85a1a46500135 (patch) | |
tree | e06f14d183b255d4bb3d257328e666b13eec089a /gcc | |
parent | 3d092c45bf57b3f9df0892e8d95a6284106a86c2 (diff) | |
download | gcc-2ef571e2c282999a7c3f46e6a0b85a1a46500135.zip gcc-2ef571e2c282999a7c3f46e6a0b85a1a46500135.tar.gz gcc-2ef571e2c282999a7c3f46e6a0b85a1a46500135.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr23234.c | 52 | ||||
-rw-r--r-- | gcc/tree-ssa-math-opts.c | 35 |
4 files changed, 93 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b01aa11..751668f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c45105e..57681cd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23234.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23234.c new file mode 100644 index 0000000..bd0b62b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23234.c @@ -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; +} diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index be2d758..456043f 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -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 = |