diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-07-26 12:37:00 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-07-26 12:37:00 +0000 |
commit | db3e66dcbb8e2564f23b42855df640272c0d54af (patch) | |
tree | 975b95703cc2a091d0283d1a5f3597ffadbc5dba | |
parent | 7b9dcf83e561d62d383c4c63aa57c309c5bc7d0e (diff) | |
download | gcc-db3e66dcbb8e2564f23b42855df640272c0d54af.tar.gz |
2011-07-26 Richard Guenther <rguenther@suse.de>
PR tree-optimization/49840
* tree-vrp.c (range_fits_type_p): Properly handle full
double-int precision.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@176790 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 26 |
2 files changed, 30 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7825a25882f..74f58cdde69 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-07-26 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/49840 + * tree-vrp.c (range_fits_type_p): Properly handle full + double-int precision. + 2011-07-26 Martin Jambor <mjambor@suse.cz> PR bootstrap/49786 diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index c6a4c4476ff..1756dd25bd3 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -7423,18 +7423,40 @@ simplify_conversion_using_ranges (gimple stmt) static bool range_fits_type_p (value_range_t *vr, unsigned precision, bool unsigned_p) { + tree src_type; + unsigned src_precision; double_int tem; - /* We can only handle constant ranges. */ + /* We can only handle integral and pointer types. */ + src_type = TREE_TYPE (vr->min); + if (!INTEGRAL_TYPE_P (src_type) + && !POINTER_TYPE_P (src_type)) + return false; + + /* An extension is always fine, so is an identity transform. */ + src_precision = TYPE_PRECISION (TREE_TYPE (vr->min)); + if (src_precision < precision + || (src_precision == precision + && TYPE_UNSIGNED (src_type) == unsigned_p)) + return true; + + /* Now we can only handle ranges with constant bounds. */ if (vr->type != VR_RANGE || TREE_CODE (vr->min) != INTEGER_CST || TREE_CODE (vr->max) != INTEGER_CST) return false; + /* For precision-preserving sign-changes the MSB of the double-int + has to be clear. */ + if (src_precision == precision + && (TREE_INT_CST_HIGH (vr->min) | TREE_INT_CST_HIGH (vr->max)) < 0) + return false; + + /* Then we can perform the conversion on both ends and compare + the result for equality. */ tem = double_int_ext (tree_to_double_int (vr->min), precision, unsigned_p); if (!double_int_equal_p (tree_to_double_int (vr->min), tem)) return false; - tem = double_int_ext (tree_to_double_int (vr->max), precision, unsigned_p); if (!double_int_equal_p (tree_to_double_int (vr->max), tem)) return false; |