From 9f61fd17476282a3c279b3b70c7cee1e12b265f5 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Tue, 26 Jul 2011 12:37:00 +0000 Subject: [PATCH] re PR middle-end/49840 (New test failures) 2011-07-26 Richard Guenther PR tree-optimization/49840 * tree-vrp.c (range_fits_type_p): Properly handle full double-int precision. From-SVN: r176790 --- gcc/ChangeLog | 6 ++++++ 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 + + PR tree-optimization/49840 + * tree-vrp.c (range_fits_type_p): Properly handle full + double-int precision. + 2011-07-26 Martin Jambor 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; -- 2.30.2