diff options
author | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2006-05-24 22:55:15 +0000 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2006-05-24 22:55:15 +0000 |
commit | d7f5de76fdc534c7eb7bb532b212936665ec2080 (patch) | |
tree | 1cb568e88ce4a846caaddba12bd18eb12329f4b8 /gcc/tree-vrp.c | |
parent | 91f8ce668b14d42e1bcbead322f869009fc896f0 (diff) | |
download | gcc-d7f5de76fdc534c7eb7bb532b212936665ec2080.zip gcc-d7f5de76fdc534c7eb7bb532b212936665ec2080.tar.gz gcc-d7f5de76fdc534c7eb7bb532b212936665ec2080.tar.bz2 |
re PR tree-optimization/27639 (VRP miscompilation of simple loop)
PR tree-optimization/27639
PR tree-optimization/26719
* tree-vrp.c (adjust_range_with_scev): Use scev_direction and adjust
call to scev_probably_wraps_p.
* tree-ssa-loop-niter.c (compare_trees, convert_step_widening,
used_in_pointer_arithmetic_p, convert_step): Removed.
(nowrap_type_p): New function.
(scev_probably_wraps_p): Rewritten.
* tree-scalar-evolution.c (instantiate_parameters_1): Do not call
chrec_convert if chrec_convert_aggressive might have been used.
* tree-chrec.c (convert_affine_scev, chrec_convert_1,
scev_direction): New functions.
(chrec_convert): Changed to a wrapper over chrec_convert_1.
* tree-ssa-loop-ivopts.c (idx_find_step): Use convert_affine_scev
instead of convert_step.
* tree-flow.h (scev_probably_wraps_p): Declaration changed.
(convert_step): Declaration removed.
(convert_affine_scev, nowrap_type_p, scev_direction): Declare.
* gcc.dg/pr27639.c: New test.
* gcc.dg/pr26719.c: New test.
* gcc.dg/tree-ssa/scev-cast.c: New test.
From-SVN: r114057
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 1734d44..11c8077 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1975,7 +1975,7 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt, tree var) { tree init, step, chrec; - bool init_is_max, unknown_max; + enum ev_direction dir; /* TODO. Don't adjust anti-ranges. An anti-range may provide better opportunities than a regular range, but I'm not sure. */ @@ -1998,11 +1998,14 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt, || !valid_value_p (init)) return; - /* Do not adjust ranges when chrec may wrap. */ - if (scev_probably_wraps_p (chrec_type (chrec), init, step, stmt, - current_loops->parray[CHREC_VARIABLE (chrec)], - &init_is_max, &unknown_max) - || unknown_max) + dir = scev_direction (chrec); + if (/* Do not adjust ranges if we do not know whether the iv increases + or decreases, ... */ + dir == EV_DIR_UNKNOWN + /* ... or if it may wrap. */ + || scev_probably_wraps_p (init, step, stmt, + current_loops->parray[CHREC_VARIABLE (chrec)], + true)) return; if (!POINTER_TYPE_P (TREE_TYPE (init)) @@ -2013,7 +2016,7 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt, tree min = TYPE_MIN_VALUE (TREE_TYPE (init)); tree max = TYPE_MAX_VALUE (TREE_TYPE (init)); - if (init_is_max) + if (dir == EV_DIR_DECREASES) max = init; else min = init; @@ -2031,7 +2034,7 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt, tree min = vr->min; tree max = vr->max; - if (init_is_max) + if (dir == EV_DIR_DECREASES) { /* INIT is the maximum value. If INIT is lower than VR->MAX but no smaller than VR->MIN, set VR->MAX to INIT. */ |