diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-05-01 21:30:26 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-05-01 21:30:26 +0000 |
commit | ccab2921c9a8ee3cf711a2bc7f62b4963f943bc6 (patch) | |
tree | 97f124b29810b764f35f68f70433b948f8558b80 /gcc/tree-vrp.c | |
parent | 15238db85a4b38dbef4b5d52190421bcbe6cd274 (diff) | |
download | gcc-ccab2921c9a8ee3cf711a2bc7f62b4963f943bc6.tar.gz |
2010-05-01 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43949
* tree-vrp.c (ssa_name_nonnegative_p): Return true for unsigned
types.
(extract_range_from_binary_expr): Handle *_MOD_EXPR.
* g++.dg/warn/Warray-bounds-5.C: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158965 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index d8ebbe8f369..83ff665c61d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1364,6 +1364,10 @@ ssa_name_nonnegative_p (const_tree t) { value_range_t *vr = get_value_range (t); + if (INTEGRAL_TYPE_P (t) + && TYPE_UNSIGNED (t)) + return true; + if (!vr) return false; @@ -2079,6 +2083,10 @@ extract_range_from_binary_expr (value_range_t *vr, && code != CEIL_DIV_EXPR && code != EXACT_DIV_EXPR && code != ROUND_DIV_EXPR + && code != TRUNC_MOD_EXPR + && code != FLOOR_MOD_EXPR + && code != CEIL_MOD_EXPR + && code != ROUND_MOD_EXPR && code != RSHIFT_EXPR && code != MIN_EXPR && code != MAX_EXPR @@ -2147,6 +2155,10 @@ extract_range_from_binary_expr (value_range_t *vr, && code != CEIL_DIV_EXPR && code != EXACT_DIV_EXPR && code != ROUND_DIV_EXPR + && code != TRUNC_MOD_EXPR + && code != FLOOR_MOD_EXPR + && code != CEIL_MOD_EXPR + && code != ROUND_MOD_EXPR && (vr0.type == VR_VARYING || vr1.type == VR_VARYING || vr0.type != vr1.type @@ -2497,6 +2509,28 @@ extract_range_from_binary_expr (value_range_t *vr, } } } + else if (code == TRUNC_MOD_EXPR + || code == FLOOR_MOD_EXPR + || code == CEIL_MOD_EXPR + || code == ROUND_MOD_EXPR) + { + bool sop = false; + if (vr0.type == VR_ANTI_RANGE + || vr1.type != VR_RANGE + || symbolic_range_p (&vr1) + || range_includes_zero_p (&vr1)) + { + set_value_range_to_varying (vr); + return; + } + type = VR_RANGE; + max = int_const_binop (MINUS_EXPR, vr1.max, integer_one_node, 0); + if (vrp_expr_computes_nonnegative (op0, &sop) + && vrp_expr_computes_nonnegative (op1, &sop) && !sop) + min = build_int_cst (TREE_TYPE (vr1.max), 0); + else + min = fold_unary (NEGATE_EXPR, TREE_TYPE (max), max); + } else if (code == MINUS_EXPR) { /* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to |