diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-09 12:39:11 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-09 12:39:11 +0000 |
commit | 0086a3d6f91f6b6adecf17f1399939aeeacb2e37 (patch) | |
tree | 8f2366195492eca232eb1a6d8a000c1d7b4d5757 /gcc/tree-vrp.c | |
parent | c8aa8448d8bcff74b6217d70fb9f60c0af32f317 (diff) | |
download | gcc-0086a3d6f91f6b6adecf17f1399939aeeacb2e37.tar.gz |
2006-06-09 Richard Guenther <rguenther@suse.de>
PR tree-optimization/26998
* tree-vrp.c (extract_range_from_unary_expr): For NEGATE_EXPR
of signed types, only TYPE_MIN_VALUE is special, but for both,
minimum and maximum value. Likewise VR_ANTI_RANGE is special
in this case, as is -fwrapv.
* gcc.dg/torture/pr26998.c: New testcase.
* gcc.dg/tree-ssa/vrp29.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114507 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 3ac01fb70f3..9eac7e9b67d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1795,14 +1795,21 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) if (code == NEGATE_EXPR && !TYPE_UNSIGNED (TREE_TYPE (expr))) { - /* NEGATE_EXPR flips the range around. */ - min = (vr0.max == TYPE_MAX_VALUE (TREE_TYPE (expr)) && !flag_wrapv) - ? TYPE_MIN_VALUE (TREE_TYPE (expr)) - : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max); - - max = (vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)) && !flag_wrapv) - ? TYPE_MAX_VALUE (TREE_TYPE (expr)) - : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min); + /* NEGATE_EXPR flips the range around. We need to treat + TYPE_MIN_VALUE specially dependent on wrapping, range type + and if it was used as minimum or maximum value: + -~[MIN, MIN] == ~[MIN, MIN] + -[MIN, 0] == [0, MAX] for -fno-wrapv + -[MIN, 0] == [0, MIN] for -fwrapv (will be set to varying later) */ + min = vr0.max == TYPE_MIN_VALUE (TREE_TYPE (expr)) + ? TYPE_MIN_VALUE (TREE_TYPE (expr)) + : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max); + + max = vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)) + ? (vr0.type == VR_ANTI_RANGE || flag_wrapv + ? TYPE_MIN_VALUE (TREE_TYPE (expr)) + : TYPE_MAX_VALUE (TREE_TYPE (expr))) + : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min); } else if (code == NEGATE_EXPR |