From ad071b2b638eac3038dbd6f12dea7c21fbbfe863 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 10 Jun 2016 10:23:06 -0600 Subject: [PATCH] re PR tree-optimization/71335 (wrong code at -O2 and -O3 in 32-bit and 64-bit modes on x86_64-linux-gnu) PR tree-optimization/71335 * tree-ssa-threadbackward.c (profitable_jump_thread_path): Filter out zero length paths here. (convert_and_register_jump_thread_path): Remove hacks related to duplicated blocks in the jump thread path. (fsm_find_control_statement_thread_paths): Avoid putting the same block on the thread path twice, but ensure the thread path is unchanged from the caller's point of view. PR tree-optimization/71335 * gcc.c-torture/execute/pr71335.c: New test. From-SVN: r237312 --- gcc/ChangeLog | 11 +++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.c-torture/execute/pr71335.c | 13 ++++++ gcc/tree-ssa-threadbackward.c | 44 +++++++++---------- 4 files changed, 51 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr71335.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af960257eae..bd9476ea931 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2016-06-10 Jeff Law + + PR tree-optimization/71335 + * tree-ssa-threadbackward.c (profitable_jump_thread_path): Filter out + zero length paths here. + (convert_and_register_jump_thread_path): Remove hacks related to + duplicated blocks in the jump thread path. + (fsm_find_control_statement_thread_paths): Avoid putting the same + block on the thread path twice, but ensure the thread path is + unchanged from the caller's point of view. + 2016-06-10 Jan Hubicka * predict.c (predict_loops): Remove PRED_LOOP_BRANCH. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 71a2db10ab7..b76e477d3e5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-06-10 Jeff Law + + PR tree-optimization/71335 + * gcc.c-torture/execute/pr71335.c: New test. + 2016-06-10 David Malcolm * gcc.dg/plugin/must-tail-call-2.c: Remove all details from diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71335.c b/gcc/testsuite/gcc.c-torture/execute/pr71335.c new file mode 100644 index 00000000000..cbfd99083d0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr71335.c @@ -0,0 +1,13 @@ +int a; +int +main () +{ + int b = 0; + while (a < 0 || b) + { + b = 0; + for (; b < 9; b++) + ; + } + exit (0); +} diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c index 57f1f5c54da..139d376d1cb 100644 --- a/gcc/tree-ssa-threadbackward.c +++ b/gcc/tree-ssa-threadbackward.c @@ -109,6 +109,19 @@ profitable_jump_thread_path (vec *&path, /* 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. */ int path_length = path->length (); + + /* We can get a length of 0 here when the statement that + makes a conditional generate a compile-time constant + result is in the same block as the conditional. + + That's not really a jump threading opportunity, but instead is + simple cprop & simplification. We could handle it here if we + wanted by wiring up all the incoming edges. If we run this + early in IPA, that might be worth doing. For now we just + reject that case. */ + if (path_length == 0) + return NULL; + if (path_length + 1 > PARAM_VALUE (PARAM_MAX_FSM_THREAD_LENGTH)) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -376,34 +389,12 @@ convert_and_register_jump_thread_path (vec *&path, basic_block bb1 = (*path)[path->length () - j - 1]; basic_block bb2 = (*path)[path->length () - j - 2]; - /* This can happen when we have an SSA_NAME as a PHI argument and - its initialization block is the head of the PHI argument's - edge. */ - if (bb1 == bb2) - continue; - edge e = find_edge (bb1, bb2); gcc_assert (e); jump_thread_edge *x = new jump_thread_edge (e, EDGE_FSM_THREAD); jump_thread_path->safe_push (x); } - /* As a consequence of the test for duplicate blocks in the path - above, we can get a path with no blocks. This happens if a - conditional can be fully evaluated at compile time using just - defining statements in the same block as the test. - - When we no longer push the block associated with a PHI argument - onto the stack, then this as well as the test in the loop above - can be removed. */ - if (jump_thread_path->length () == 0) - { - jump_thread_path->release (); - delete jump_thread_path; - path->pop (); - return; - } - /* Add the edge taken when the control variable has value ARG. */ jump_thread_edge *x = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK); @@ -579,10 +570,19 @@ fsm_find_control_statement_thread_paths (tree name, else { + /* profitable_jump_thread_path is going to push the current + block onto the path. But the path will always have the current + block at this point. So we can just pop it. */ + path->pop (); + edge taken_edge = profitable_jump_thread_path (path, var_bb, name, arg); if (taken_edge) convert_and_register_jump_thread_path (path, taken_edge); + + /* And put the current block back onto the path so that the + state of the stack is unchanged when we leave. */ + vec_safe_push (path, var_bb); } } -- 2.30.2