aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tom@codesourcery.com>2012-09-07 09:21:11 +0000
committerTom de Vries <vries@gcc.gnu.org>2012-09-07 09:21:11 +0000
commit25722436a61aa310416ceb64254e634236442d05 (patch)
treebda2e1246830004bdba5e494204e07215b78dc4d
parent7fb3b7a74699bd0dc6a1630756b4bb1ac31658a4 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/tree-vrp.c24
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;