From 71fa3334cbf5c0de7bb3d5bec266f29c64e66d23 Mon Sep 17 00:00:00 2001 From: rguenth Date: Tue, 27 Aug 2013 10:10:34 +0000 Subject: [PATCH] 2013-08-27 Richard Biener PR tree-optimization/57521 * tree-if-conv.c (if_convertible_bb_p): Verify that at least one edge is non-critical. (find_phi_replacement_condition): Make sure to use a non-critical edge. Cleanup and remove old bug workarounds. (bb_postdominates_preds): Remove. (if_convertible_loop_p_1): Do not compute post-dominators. (combine_blocks): Do not free post-dominators. (main_tree_if_conversion): Likewise. (pass_data_if_conversion): Add TODO_verify_ssa. * gcc.dg/torture/pr57521.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@202019 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 13 +++++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/torture/pr57521.c | 51 ++++++++++++++++++++ gcc/tree-if-conv.c | 88 ++++++++++------------------------ 4 files changed, 95 insertions(+), 62 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr57521.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 213b78c2422..04ed1616071 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2013-08-27 Richard Biener + + PR tree-optimization/57521 + * tree-if-conv.c (if_convertible_bb_p): Verify that at least + one edge is non-critical. + (find_phi_replacement_condition): Make sure to use a non-critical + edge. Cleanup and remove old bug workarounds. + (bb_postdominates_preds): Remove. + (if_convertible_loop_p_1): Do not compute post-dominators. + (combine_blocks): Do not free post-dominators. + (main_tree_if_conversion): Likewise. + (pass_data_if_conversion): Add TODO_verify_ssa. + 2013-08-27 DJ Delorie * config/i386/djgpp.h (ASM_DECLARE_FUNCTION_NAME): New. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5310441f854..9e0951b693a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-08-27 Richard Biener + + PR tree-optimization/57521 + * gcc.dg/torture/pr57521.c: New testcase. + 2013-08-27 Jakub Jelinek PR rtl-optimization/57860 diff --git a/gcc/testsuite/gcc.dg/torture/pr57521.c b/gcc/testsuite/gcc.dg/torture/pr57521.c new file mode 100644 index 00000000000..e7832cb00e8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57521.c @@ -0,0 +1,51 @@ +/* { dg-do run } */ +/* { dg-options "-ftree-loop-if-convert" } */ + +void abort (void); + +int a, b, c, d, o = 1, p; +short e; + +int +fn1 (int * p1) +{ + int f, g, h, j = 0, k = 0, l = 0; + unsigned int i; + int *m[1] = { &l }; + for (; b >= 0; b--) + { + if (*p1) + if (j >= 0) + { + int n = 1; + e = 1; + h = a ? a : 1 % n; + g = h > 0 ? 0 : h + 1; + k = c + g; + } + else + continue; + else + { + + f = d > 0 ? 0 : d + 1; + i = f; + j = 1 + i; + } + l++; + } + return k; +} + +int +main () +{ + for (;; p++) + { + fn1 (&o); + break; + } + if (e != 1) + abort (); + return 0; +} diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index a886169ed00..6ec9c0f5050 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -797,20 +797,6 @@ if_convertible_stmt_p (gimple stmt, vec refs) return true; } -/* Return true when BB post-dominates all its predecessors. */ - -static bool -bb_postdominates_preds (basic_block bb) -{ - unsigned i; - - for (i = 0; i < EDGE_COUNT (bb->preds); i++) - if (!dominated_by_p (CDI_POST_DOMINATORS, EDGE_PRED (bb, i)->src, bb)) - return false; - - return true; -} - /* Return true when BB is if-convertible. This routine does not check basic block's statements and phis. @@ -868,10 +854,23 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb) return false; } - if (EDGE_COUNT (bb->preds) == 2 - && bb != loop->header - && !bb_postdominates_preds (bb)) - return false; + /* At least one incoming edge has to be non-critical as otherwise edge + predicates are not equal to basic-block predicates of the edge + source. */ + if (EDGE_COUNT (bb->preds) > 1 + && bb != loop->header) + { + bool found = false; + FOR_EACH_EDGE (e, ei, bb->preds) + if (EDGE_COUNT (e->src->succs) == 1) + found = true; + if (!found) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "only critical predecessors\n"); + return false; + } + } return true; } @@ -1084,7 +1083,6 @@ if_convertible_loop_p_1 (struct loop *loop, return false; calculate_dominance_info (CDI_DOMINATORS); - calculate_dominance_info (CDI_POST_DOMINATORS); /* Allow statements that can be handled during if-conversion. */ ifc_bbs = get_loop_body_in_if_conv_order (loop); @@ -1220,8 +1218,7 @@ if_convertible_loop_p (struct loop *loop) if-conversion. */ static basic_block -find_phi_replacement_condition (struct loop *loop, - basic_block bb, tree *cond, +find_phi_replacement_condition (basic_block bb, tree *cond, gimple_stmt_iterator *gsi) { edge first_edge, second_edge; @@ -1231,34 +1228,10 @@ find_phi_replacement_condition (struct loop *loop, first_edge = EDGE_PRED (bb, 0); second_edge = EDGE_PRED (bb, 1); - /* Use condition based on following criteria: - 1) - S1: x = !c ? a : b; - - S2: x = c ? b : a; - - S2 is preferred over S1. Make 'b' first_bb and use its condition. - - 2) Do not make loop header first_bb. - - 3) - S1: x = !(c == d)? a : b; - - S21: t1 = c == d; - S22: x = t1 ? b : a; - - S3: x = (c == d) ? b : a; - - S3 is preferred over S1 and S2*, Make 'b' first_bb and use - its condition. - - 4) If pred B is dominated by pred A then use pred B's condition. - See PR23115. */ - - /* Select condition that is not TRUTH_NOT_EXPR. */ + /* Prefer an edge with a not negated predicate. + ??? That's a very weak cost model. */ tmp_cond = bb_predicate (first_edge->src); gcc_assert (tmp_cond); - if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR) { edge tmp_edge; @@ -1268,11 +1241,9 @@ find_phi_replacement_condition (struct loop *loop, second_edge = tmp_edge; } - /* Check if FIRST_BB is loop header or not and make sure that - FIRST_BB does not dominate SECOND_BB. */ - if (first_edge->src == loop->header - || dominated_by_p (CDI_DOMINATORS, - second_edge->src, first_edge->src)) + /* Check if the edge we take the condition from is not critical. + We know that at least one non-critical edge exists. */ + if (EDGE_COUNT (first_edge->src->succs) > 1) { *cond = bb_predicate (second_edge->src); @@ -1347,9 +1318,6 @@ predicate_scalar_phi (gimple phi, tree cond, arg_1 = gimple_phi_arg_def (phi, 1); } - gcc_checking_assert (bb == bb->loop_father->header - || bb_postdominates_preds (bb)); - /* Build new RHS using selected condition and arguments. */ rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond), arg_0, arg_1); @@ -1395,7 +1363,7 @@ predicate_all_scalar_phis (struct loop *loop) /* BB has two predecessors. Using predecessor's aux field, set appropriate condition for the PHI node replacement. */ gsi = gsi_after_labels (bb); - true_bb = find_phi_replacement_condition (loop, bb, &cond, &gsi); + true_bb = find_phi_replacement_condition (bb, &cond, &gsi); while (!gsi_end_p (phi_gsi)) { @@ -1765,9 +1733,6 @@ combine_blocks (struct loop *loop) free (ifc_bbs); ifc_bbs = NULL; - - /* Post-dominators are corrupt now. */ - free_dominance_info (CDI_POST_DOMINATORS); } /* If-convert LOOP when it is legal. For the moment this pass has no @@ -1830,8 +1795,6 @@ main_tree_if_conversion (void) if (changed && flag_tree_loop_if_convert_stores) todo |= TODO_update_ssa_only_virtuals; - free_dominance_info (CDI_POST_DOMINATORS); - #ifdef ENABLE_CHECKING { basic_block bb; @@ -1867,7 +1830,8 @@ const pass_data pass_data_if_conversion = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - ( TODO_verify_stmts | TODO_verify_flow ), /* todo_flags_finish */ + ( TODO_verify_stmts | TODO_verify_flow + | TODO_verify_ssa ), /* todo_flags_finish */ }; class pass_if_conversion : public gimple_opt_pass -- 2.11.4.GIT