From: Tom de Vries Date: Fri, 7 Sep 2012 09:21:11 +0000 (+0000) Subject: re PR tree-optimization/53986 (missing vrp on bit-mask test, LSHIFT_EXPR not handled) X-Git-Tag: misc/gccgo-go1_1_2~997 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=25722436a61aa310416ceb64254e634236442d05;p=thirdparty%2Fgcc.git re PR tree-optimization/53986 (missing vrp on bit-mask test, LSHIFT_EXPR not handled) 2012-09-07 Tom de Vries 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 353978190c97..3e3cf363a45b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-09-07 Tom de Vries + + 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 * config/rs6000/aix43.h (RS6000_CALL_GLUE): Delete. diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 9309264092ac..47c68d8710c7 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;