From: Jeff Law Date: Mon, 3 Oct 2016 19:28:24 +0000 (-0600) Subject: re PR tree-optimization/71550 (wrong code at -O3 on x86_64-linux-gnu) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0a4e5cf3122f8237d840b34d0515151b61ffeb5e;p=gcc.git re PR tree-optimization/71550 (wrong code at -O3 on x86_64-linux-gnu) PR tree-optimization/71550 PR tree-optimization/71403 * tree-ssa-threadbackward.c: Include tree-vectorizer.h (profitable_jump_thread_path): Also return boolean indicating if the realized path will create an irreducible loop. Remove loop depth tests from 71403. (fsm_find_control_statement_thread_paths): Remove loop depth tests from 71403. If threading will create an irreducible loop, then throw away loop iteration and related information. PR tree-optimization/71550 PR tree-optimization/71403 * gcc.c-torture/execute/pr71550.c: New test. From-SVN: r240727 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f4e311087f..ba56e636584 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2016-10-03 Jeff Law + + PR tree-optimization/71550 + PR tree-optimization/71403 + * tree-ssa-threadbackward.c: Include tree-vectorizer.h + (profitable_jump_thread_path): Also return boolean indicating if + the realized path will create an irreducible loop. + Remove loop depth tests from 71403. + (fsm_find_control_statement_thread_paths): Remove loop depth tests + from 71403. If threading will create an irreducible loop, then + throw away loop iteration and related information. + 2016-10-03 Uros Bizjak * configure.ac (strict_warn): Merge -Wmissing-format-attribute and diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d0ed6a679b4..9e6246455ca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-09-26 Jeff Law + + PR tree-optimization/71550 + PR tree-optimization/71403 + * gcc.c-torture/execute/pr71550.c: New test. + 2016-10-03 Senthil Kumar Selvaraj * gcc.target/avr/torture/builtins-error.c: Add -ffat-lto-objects diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71550.c b/gcc/testsuite/gcc.c-torture/execute/pr71550.c new file mode 100644 index 00000000000..8d1ecdaa06d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr71550.c @@ -0,0 +1,26 @@ + +extern void exit (int); + +int a = 3, b, c, f, g, h; +unsigned d; +char *e; + +int +main () +{ + for (; a; a--) + { + int i; + if (h && i) + __builtin_printf ("%d%d", c, f); + i = 0; + for (; i < 2; i++) + if (g) + for (; d < 10; d++) + b = *e; + i = 0; + for (; i < 1; i++) + ; + } + exit (0); +} diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c index 6b522adcefb..fd7d855449d 100644 --- a/gcc/tree-ssa-threadbackward.c +++ b/gcc/tree-ssa-threadbackward.c @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-ssa.h" #include "tree-phinodes.h" #include "tree-inline.h" +#include "tree-vectorizer.h" static int max_threaded_paths; @@ -110,7 +111,8 @@ fsm_find_thread_path (basic_block start_bb, basic_block end_bb, static edge profitable_jump_thread_path (vec *&path, - basic_block bbi, tree name, tree arg, bool speed_p) + basic_block bbi, tree name, tree arg, bool speed_p, + bool *creates_irreducible_loop) { /* Note BBI is not in the path yet, hence the +1 in the test below to make sure BBI is accounted for in the path length test. */ @@ -296,12 +298,12 @@ profitable_jump_thread_path (vec *&path, return NULL; } - bool creates_irreducible_loop = false; + *creates_irreducible_loop = false; if (threaded_through_latch && loop == taken_edge->dest->loop_father && (determine_bb_domination_status (loop, taken_edge->dest) == DOMST_NONDOMINATING)) - creates_irreducible_loop = true; + *creates_irreducible_loop = true; if (path_crosses_loops) { @@ -343,7 +345,7 @@ profitable_jump_thread_path (vec *&path, the path -- in that case there's little the traditional loop optimizer would have done anyway, so an irreducible loop is not so bad. */ - if (!threaded_multiway_branch && creates_irreducible_loop + if (!threaded_multiway_branch && *creates_irreducible_loop && (n_insns * PARAM_VALUE (PARAM_FSM_SCALE_PATH_STMTS) > path_length * PARAM_VALUE (PARAM_FSM_SCALE_PATH_BLOCKS))) @@ -479,9 +481,6 @@ fsm_find_control_statement_thread_paths (tree name, seen_loop_phi = true; } - if (bb_loop_depth (last_bb_in_path) > bb_loop_depth (var_bb)) - return; - /* Following the chain of SSA_NAME definitions, we jumped from a definition in LAST_BB_IN_PATH to a definition in VAR_BB. When these basic blocks are different, append to PATH the blocks from LAST_BB_IN_PATH to VAR_BB. */ @@ -528,9 +527,7 @@ fsm_find_control_statement_thread_paths (tree name, NEXT_PATH. Don't add them here to avoid pollution. */ for (unsigned int i = 0; i < next_path->length () - 1; i++) { - if (visited_bbs->contains ((*next_path)[i]) - || (bb_loop_depth (last_bb_in_path) - > bb_loop_depth ((*next_path)[i]))) + if (visited_bbs->contains ((*next_path)[i])) { vec_free (next_path); return; @@ -580,14 +577,16 @@ fsm_find_control_statement_thread_paths (tree name, /* If this is a profitable jump thread path, then convert it into the canonical form and register it. */ + bool irreducible = false; edge taken_edge = profitable_jump_thread_path (path, bbi, name, arg, - speed_p); + speed_p, &irreducible); if (taken_edge) { - if (bb_loop_depth (taken_edge->src) - >= bb_loop_depth (taken_edge->dest)) - convert_and_register_jump_thread_path (path, taken_edge); + convert_and_register_jump_thread_path (path, taken_edge); path->pop (); + + if (irreducible) + vect_free_loop_info_assumptions ((*path)[0]->loop_father); } } } @@ -606,14 +605,17 @@ fsm_find_control_statement_thread_paths (tree name, block at this point. So we can just pop it. */ path->pop (); + bool irreducible = false; edge taken_edge = profitable_jump_thread_path (path, var_bb, - name, arg, speed_p); + name, arg, speed_p, + &irreducible); if (taken_edge) { - if (bb_loop_depth (taken_edge->src) - >= bb_loop_depth (taken_edge->dest)) - convert_and_register_jump_thread_path (path, taken_edge); + convert_and_register_jump_thread_path (path, taken_edge); path->pop (); + + if (irreducible) + vect_free_loop_info_assumptions ((*path)[0]->loop_father); } /* And put the current block back onto the path so that the