diff options
author | Tom de Vries <tom@codesourcery.com> | 2012-09-07 09:21:11 +0000 |
---|---|---|
committer | Tom de Vries <vries@gcc.gnu.org> | 2012-09-07 09:21:11 +0000 |
commit | 25722436a61aa310416ceb64254e634236442d05 (patch) | |
tree | bda2e1246830004bdba5e494204e07215b78dc4d /gcc | |
parent | 7fb3b7a74699bd0dc6a1630756b4bb1ac31658a4 (diff) | |
download | gcc-25722436a61aa310416ceb64254e634236442d05.zip gcc-25722436a61aa310416ceb64254e634236442d05.tar.gz gcc-25722436a61aa310416ceb64254e634236442d05.tar.bz2 |
re PR tree-optimization/53986 (missing vrp on bit-mask test, LSHIFT_EXPR not handled)
2012-09-07 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/53986
* tree-vrp.c (extract_range_from_multiplicative_op_1): Allow
LSHIFT_EXPR.
(extract_range_from_binary_expr_1): Handle LSHIFT with constant range as
shift amount.
From-SVN: r191057
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 24 |
2 files changed, 31 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3539781..3e3cf36 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-09-07 Tom de Vries <tom@codesourcery.com> + + PR tree-optimization/53986 + * tree-vrp.c (extract_range_from_multiplicative_op_1): Allow + LSHIFT_EXPR. + (extract_range_from_binary_expr_1): Handle LSHIFT with constant range as + shift amount. + 2012-09-07 Segher Boessenkool <segher@kernel.crashing.org> * config/rs6000/aix43.h (RS6000_CALL_GLUE): Delete. diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 9309264..47c68d8 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -2066,7 +2066,8 @@ extract_range_from_multiplicative_op_1 (value_range_t *vr, || code == CEIL_DIV_EXPR || code == EXACT_DIV_EXPR || code == ROUND_DIV_EXPR - || code == RSHIFT_EXPR); + || code == RSHIFT_EXPR + || code == LSHIFT_EXPR); gcc_assert ((vr0->type == VR_RANGE || (code == MULT_EXPR && vr0->type == VR_ANTI_RANGE)) && vr0->type == vr1->type); @@ -2762,6 +2763,27 @@ extract_range_from_binary_expr_1 (value_range_t *vr, flag_wrapv = saved_flag_wrapv; return; } + else if (code == LSHIFT_EXPR + && range_int_cst_p (&vr0)) + { + int overflow_pos = TYPE_PRECISION (expr_type); + int bound_shift; + double_int bound; + + if (!TYPE_UNSIGNED (expr_type)) + overflow_pos -= 1; + + bound_shift = overflow_pos - TREE_INT_CST_LOW (vr1.max); + bound = double_int_one.llshift (bound_shift, + TYPE_PRECISION (expr_type)); + if (tree_to_double_int (vr0.max).ult (bound)) + { + /* In the absense of overflow, (a << b) is equivalent + to (a * 2^b). */ + extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1); + return; + } + } } set_value_range_to_varying (vr); return; |