[PATCH] Fix PR54767

Richard Biener rguenther@suse.de
Tue Jan 15 12:41:00 GMT 2013


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  <rguenther@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



More information about the Gcc-patches mailing list