aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2006-08-17 10:22:05 +0200
committerZdenek Dvorak <rakdver@gcc.gnu.org>2006-08-17 08:22:05 +0000
commit2052721560b2329471c637b4d20f8fef44363004 (patch)
treec20e13777a5de4b4baf2a2a1fb88f0351d8a1b0e /gcc/tree-vrp.c
parentb646edb85c5be9813851a21cddf0e9472d4023c2 (diff)
downloadgcc-2052721560b2329471c637b4d20f8fef44363004.zip
gcc-2052721560b2329471c637b4d20f8fef44363004.tar.gz
gcc-2052721560b2329471c637b4d20f8fef44363004.tar.bz2
re PR tree-optimization/27865 (tree check failure building FreePOOMA)
PR tree-optimization/27865 * tree-vrp.c (adjust_range_with_scev): Do not use TYPE_{MIN,MAX}_VALUE for pointer types. * tree-scalar-evolution.c (fold_used_pointer_cast, pointer_offset_p, fold_used_pointer, pointer_used_p): New functions. (analyze_scalar_evolution_1): Use fold_used_pointer. * tree-chrec.c (convert_affine_scev): Convert no-op casts correctly. * tree-ssa-loop-ivopts.c (generic_type_for): Return integral type for pointers. From-SVN: r116213
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 335ae61..5f53211 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -2015,7 +2015,7 @@ static void
adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
tree var)
{
- tree init, step, chrec;
+ tree init, step, chrec, tmin, tmax, min, max, type;
enum ev_direction dir;
/* TODO. Don't adjust anti-ranges. An anti-range may provide
@@ -2049,13 +2049,23 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
true))
return;
- if (!POINTER_TYPE_P (TREE_TYPE (init))
- && (vr->type == VR_VARYING || vr->type == VR_UNDEFINED))
+ type = TREE_TYPE (var);
+ if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
+ tmin = lower_bound_in_type (type, type);
+ else
+ tmin = TYPE_MIN_VALUE (type);
+ if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
+ tmax = upper_bound_in_type (type, type);
+ else
+ tmax = TYPE_MAX_VALUE (type);
+
+ if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
{
+ min = tmin;
+ max = tmax;
+
/* For VARYING or UNDEFINED ranges, just about anything we get
from scalar evolutions should be better. */
- tree min = TYPE_MIN_VALUE (TREE_TYPE (init));
- tree max = TYPE_MAX_VALUE (TREE_TYPE (init));
if (dir == EV_DIR_DECREASES)
max = init;
@@ -2064,7 +2074,8 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
/* If we would create an invalid range, then just assume we
know absolutely nothing. This may be over-conservative,
- but it's clearly safe. */
+ but it's clearly safe, and should happen only in unreachable
+ parts of code, or for invalid programs. */
if (compare_values (min, max) == 1)
return;
@@ -2072,8 +2083,8 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
}
else if (vr->type == VR_RANGE)
{
- tree min = vr->min;
- tree max = vr->max;
+ min = vr->min;
+ max = vr->max;
if (dir == EV_DIR_DECREASES)
{
@@ -2084,10 +2095,11 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
max = init;
/* If we just created an invalid range with the minimum
- greater than the maximum, take the minimum all the
- way to -INF. */
+ greater than the maximum, we fail conservatively.
+ This should happen only in unreachable
+ parts of code, or for invalid programs. */
if (compare_values (min, max) == 1)
- min = TYPE_MIN_VALUE (TREE_TYPE (min));
+ return;
}
}
else
@@ -2097,11 +2109,9 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
{
min = init;
- /* If we just created an invalid range with the minimum
- greater than the maximum, take the maximum all the
- way to +INF. */
+ /* Again, avoid creating invalid range by failing. */
if (compare_values (min, max) == 1)
- max = TYPE_MAX_VALUE (TREE_TYPE (max));
+ return;
}
}