-----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
      {

Reply via email to