This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR43796
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 19 Apr 2010 17:16:08 +0200 (CEST)
- Subject: [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
+