This fixes PR54767 - in VRP we may not propagate symbolical range information (such as equivalences - see the original fix for PR53465) across backedges. The following patch makes sure we don't by cleaning all such information when visiting PHI nodes for incoming edges marked with EDGE_DFS_BACK.
Honza - if we compute EDGE_DFS_BACK at which places can we rely (for correctnes) on it being set? On CFG confluence points (thus, PHI node incoming edges)? It seems split_edge doesn't "preserve" EDGE_DFS_BACK (the gimple variant places the new block at e->dest, thus the forwarder edge will retain EDGE_DFS_BACK). That's unfortunate and requires EDGE_DFS_BACK compute to be after assert expr insertion (even though it's also used by it ... just not relied on for correctness). Bootstrap and regtest pending on x86_64-unknown-linux-gnu (I verified PR53465 still fails w/o its original fix and is fixed by the new patch as well). Thanks, Richard. 2013-01-15 Richard Biener <rguent...@suse.de> PR tree-optimization/54767 PR tree-optimization/53465 * tree-vrp.c (vrp_meet_1): Revert original fix for PR53465. (vrp_visit_phi_node): For PHI arguments coming via backedges drop all symbolical range information. (execute_vrp): Compute backedges. * gfortran.fortran-torture/execute/pr54767.f90: New testcase. Index: gcc/tree-vrp.c =================================================================== *** gcc/tree-vrp.c (revision 195190) --- gcc/tree-vrp.c (working copy) *************** vrp_meet_1 (value_range_t *vr0, value_ra *** 7877,7893 **** if (vr0->type == VR_UNDEFINED) { ! /* Drop equivalences. See PR53465. */ ! set_value_range (vr0, vr1->type, vr1->min, vr1->max, NULL); return; } if (vr1->type == VR_UNDEFINED) { ! /* VR0 already has the resulting range, just drop equivalences. ! See PR53465. */ ! if (vr0->equiv) ! bitmap_clear (vr0->equiv); return; } --- 7877,7889 ---- if (vr0->type == VR_UNDEFINED) { ! set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr1->equiv); return; } if (vr1->type == VR_UNDEFINED) { ! /* VR0 already has the resulting range. */ return; } *************** vrp_visit_phi_node (gimple phi) *** 8012,8017 **** --- 8008,8027 ---- if (TREE_CODE (arg) == SSA_NAME) { vr_arg = *(get_value_range (arg)); + /* Do not allow equivalences or symbolic ranges to leak in from + backedges. That creates invalid equivalencies. */ + if (e->flags & EDGE_DFS_BACK + && (vr_arg.type == VR_RANGE + || vr_arg.type == VR_ANTI_RANGE)) + { + vr_arg.equiv = NULL; + if (symbolic_range_p (&vr_arg)) + { + vr_arg.type = VR_VARYING; + vr_arg.min = NULL_TREE; + vr_arg.max = NULL_TREE; + } + } } else { *************** execute_vrp (void) *** 9260,9271 **** --- 9270,9287 ---- rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); scev_initialize (); + /* ??? This ends up using stale EDGE_DFS_BACK for liveness computation. + Inserting assertions may split edges which will invalidate + EDGE_DFS_BACK. */ insert_range_assertions (); to_remove_edges.create (10); to_update_switch_stmts.create (5); threadedge_initialize_values (); + /* For visiting PHI nodes we need EDGE_DFS_BACK computed. */ + mark_dfs_back_edges (); + vrp_initialize (); ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node); vrp_finalize (); Index: gcc/testsuite/gfortran.fortran-torture/execute/pr54767.f90 =================================================================== *** gcc/testsuite/gfortran.fortran-torture/execute/pr54767.f90 (revision 0) --- gcc/testsuite/gfortran.fortran-torture/execute/pr54767.f90 (working copy) *************** *** 0 **** --- 1,31 ---- + SUBROUTINE XXX (IL, IU) + implicit none + integer, INTENT(IN) :: IL, IU + + integer :: NXX (14) = (/ 0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14 /) + integer :: ivvv, ia, ja, iaii + logical :: qop + + QOP=.FALSE. + + DO IA=IL,IU + JA=NXX(IA) + IF (.NOT. QOP .and. JA.GT.0) THEN + IAII=IA + QOP=.TRUE. + ENDIF + + IF (QOP) THEN + ivvv=IA-IAII+1 ! mis-compiled + ENDIF + ENDDO + + IF (ivvv.NE.2) THEN + call abort + ENDIF + END subroutine + + program p + implicit none + CALL XXX (1, 3) + end