-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
At the core of this PR is a case where we were threading through a successor of a joiner block where there was already an edge from the threadable successor to the final target. ie, the successor of the joiner ended with a conditional branch, after threading both arms reached the same location. For this case, we have to ensure that if the target block has PHIs that the PHI arguments are the same for both incoming edges so that when the two edges are combined into a single edge we don't lose information. We already check and reject cases where this is not true prior to registering the jump thread. Unfortunately, the updating code tried to update the PHIs when no update is necessary or desirable. I don't have a small testcase for this bug. Bootstrapped and regression tested on x86_64-unknown-linux-gnu; also built and run cpu2006 C integer benchmarks which were failing with -O2 - -fast-math. Those benchmarks run correctly with this patch applied. OK for trunk? Jeff -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJOA2YgAAoJEBRtltQi2kC7R4kH/1jRce606GysmFOjgbIapPGb PyQk4NjnrMY3WujiQOghPe6D7wRi+UCs0DLhqW7zTcBUlBAJjCTpo3DbYyfnmSHp vQu74JYeZItjMfkPRI+6JFkaUlEpGVaAqCK7+CAqI7e3qLEook05lsJfHtzOQ/60 kGeczpjWn6p7hvVj9Q5p2OCo9+tWsu+vowdQrzF/2nBTrtSyqwE4oEW9fL7h/6Sw 27/YBheJeGEf7HtwL3Pm/G0M9mEv7u57rIek2G+VweUqwmrADvI5NuVOs1mQdDTw iYY61sjSOO8iPMAATufndjhLJKATndoXmdHL9sfpYrlsDZqsF6cCrR18o+RFymo= =ylGm -----END PGP SIGNATURE-----
PR middle-end/49465 * tree-ssa-threadupate.c (fix_duplicate_block_edges): Fix condition to detect threading through joiner block. If there was already an edge to the new target, then do not change the PHI nodes. Index: tree-ssa-threadupdate.c =================================================================== *** tree-ssa-threadupdate.c (revision 175192) --- tree-ssa-threadupdate.c (working copy) *************** fix_duplicate_block_edges (struct redire *** 385,391 **** to keep its control statement and redirect an outgoing edge. Else we want to remove the control statement & edges, then create a new outgoing edge. In both cases we may need to update PHIs. */ ! if (THREAD_TARGET2 (rd->incoming_edges->e) == rd->outgoing_edge) { edge victim; edge e2; --- 385,391 ---- to keep its control statement and redirect an outgoing edge. Else we want to remove the control statement & edges, then create a new outgoing edge. In both cases we may need to update PHIs. */ ! if (THREAD_TARGET2 (rd->incoming_edges->e)) { edge victim; edge e2; *************** fix_duplicate_block_edges (struct redire *** 400,407 **** victim = find_edge (rd->dup_block, THREAD_TARGET (e)->dest); e2 = redirect_edge_and_branch (victim, THREAD_TARGET2 (e)->dest); ! /* This updates the PHI at the target of the threaded edge. */ ! copy_phi_args (e2->dest, THREAD_TARGET2 (e), e2); } else { --- 400,410 ---- victim = find_edge (rd->dup_block, THREAD_TARGET (e)->dest); e2 = redirect_edge_and_branch (victim, THREAD_TARGET2 (e)->dest); ! /* If we redirected the edge, then we need to copy PHI arguments ! at the target. If the edge already existed (e2 != victim case), ! then the PHIs in the target already have the correct arguments. */ ! if (e2 == victim) ! copy_phi_args (e2->dest, THREAD_TARGET2 (e), e2); } else {