This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR43796


This fixes a missed-optimization in VRP which happens to fix
PR43796.

Boostrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2010-04-19  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/43796
	* tree-vrp.c (adjust_range_with_scev): Lookup init and step
	from SCEV in the lattice.
	(vrp_visit_phi_node): Dump change.

	* gfortran.dg/pr43796.f90: New testcase.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c	(revision 158505)
--- gcc/tree-vrp.c	(working copy)
*************** static void
*** 3153,3159 ****
  adjust_range_with_scev (value_range_t *vr, struct loop *loop,
  			gimple stmt, tree var)
  {
!   tree init, step, chrec, tmin, tmax, min, max, type;
    enum ev_direction dir;
  
    /* TODO.  Don't adjust anti-ranges.  An anti-range may provide
--- 3153,3159 ----
  adjust_range_with_scev (value_range_t *vr, struct loop *loop,
  			gimple stmt, tree var)
  {
!   tree init, step, chrec, tmin, tmax, min, max, type, tem;
    enum ev_direction dir;
  
    /* TODO.  Don't adjust anti-ranges.  An anti-range may provide
*************** adjust_range_with_scev (value_range_t *v
*** 3174,3180 ****
--- 3174,3186 ----
      return;
  
    init = initial_condition_in_loop_num (chrec, loop->num);
+   tem = op_with_constant_singleton_value_range (init);
+   if (tem)
+     init = tem;
    step = evolution_part_in_loop_num (chrec, loop->num);
+   tem = op_with_constant_singleton_value_range (step);
+   if (tem)
+     step = tem;
  
    /* If STEP is symbolic, we can't know whether INIT will be the
       minimum or maximum value in the range.  Also, unless INIT is
*************** vrp_visit_phi_node (gimple phi)
*** 6412,6418 ****
    /* If the new range is different than the previous value, keep
       iterating.  */
    if (update_value_range (lhs, &vr_result))
!     return SSA_PROP_INTERESTING;
  
    /* Nothing changed, don't add outgoing edges.  */
    return SSA_PROP_NOT_INTERESTING;
--- 6418,6435 ----
    /* If the new range is different than the previous value, keep
       iterating.  */
    if (update_value_range (lhs, &vr_result))
!     {
!       if (dump_file && (dump_flags & TDF_DETAILS))
! 	{
! 	  fprintf (dump_file, "Found new range for ");
! 	  print_generic_expr (dump_file, lhs, 0);
! 	  fprintf (dump_file, ": ");
! 	  dump_value_range (dump_file, &vr_result);
! 	  fprintf (dump_file, "\n\n");
! 	}
! 
!       return SSA_PROP_INTERESTING;
!     }
  
    /* Nothing changed, don't add outgoing edges.  */
    return SSA_PROP_NOT_INTERESTING;
Index: gcc/testsuite/gfortran.dg/pr43796.f90
===================================================================
*** gcc/testsuite/gfortran.dg/pr43796.f90	(revision 0)
--- gcc/testsuite/gfortran.dg/pr43796.f90	(revision 0)
***************
*** 0 ****
--- 1,51 ----
+ ! { dg-do compile }
+ ! { dg-options "-O2 -fcheck=bounds" }
+ 
+     FUNCTION F06FKFN(N,W,INCW,X,INCX)
+        IMPLICIT NONE
+        INTEGER, PARAMETER :: WP = KIND(0.0D0)
+        REAL (KIND=WP)                  :: F06FKFN
+        REAL (KIND=WP), PARAMETER       :: ONE = 1.0E+0_WP
+        REAL (KIND=WP), PARAMETER       :: ZERO = 0.0E+0_WP
+        INTEGER, INTENT (IN)            :: INCW, INCX, N
+        REAL (KIND=WP), INTENT (IN)     :: W(*), X(*)
+        REAL (KIND=WP)                  :: ABSYI, NORM, SCALE, SSQ
+        INTEGER                         :: I, IW, IX
+        REAL (KIND=WP), EXTERNAL        :: F06BMFN
+        INTRINSIC                          ABS, SQRT
+        IF (N<1) THEN
+           NORM = ZERO
+        ELSE IF (N==1) THEN
+           NORM = SQRT(W(1))*ABS(X(1))
+        ELSE
+           IF (INCW>0) THEN
+              IW = 1
+           ELSE
+              IW = 1 - (N-1)*INCW
+           END IF
+           IF (INCX>0) THEN
+              IX = 1
+           ELSE
+              IX = 1 - (N-1)*INCX
+           END IF
+           SCALE = ZERO
+           SSQ = ONE
+           DO I = 1, N
+              IF ((W(IW)/=ZERO) .AND. (X(IX)/=ZERO)) THEN
+                 ABSYI = SQRT(W(IW))*ABS(X(IX))
+                 IF (SCALE<ABSYI) THEN
+                    SSQ = 1 + SSQ*(SCALE/ABSYI)**2
+                    SCALE = ABSYI
+                 ELSE
+                    SSQ = SSQ + (ABSYI/SCALE)**2
+                 END IF
+              END IF
+              IW = IW + INCW
+              IX = IX + INCX
+           END DO
+           NORM = F06BMFN(SCALE,SSQ)
+        END IF
+        F06FKFN = NORM
+        RETURN
+     END FUNCTION F06FKFN
+ 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]