summaryrefslogtreecommitdiffstats
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-21 05:58:02 +0000
committerkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-21 05:58:02 +0000
commitb3ded9f87912f68f2ecb1d8cc15aa58111ca08d0 (patch)
tree9564794f08f600e648f0a3400982f16c350506aa /gcc/tree-vrp.c
parente38498a20ed7b679f33c943387620e7d7b57bbc4 (diff)
downloadppe42-gcc-b3ded9f87912f68f2ecb1d8cc15aa58111ca08d0.tar.gz
ppe42-gcc-b3ded9f87912f68f2ecb1d8cc15aa58111ca08d0.zip
gcc/
PR tree-optimization/25382. * tree-vrp.c (extract_range_from_binary_expr): Extract a range from BIT_AND_EXPR. gcc/testsuite/ PR tree-optimization/25382. * gcc.dg/tree-ssa/pr25382.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108898 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 04353f5ad8b..a9609fa6157 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1184,6 +1184,7 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
&& code != ROUND_DIV_EXPR
&& code != MIN_EXPR
&& code != MAX_EXPR
+ && code != BIT_AND_EXPR
&& code != TRUTH_ANDIF_EXPR
&& code != TRUTH_ORIF_EXPR
&& code != TRUTH_AND_EXPR
@@ -1220,13 +1221,16 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
}
/* Refuse to operate on VARYING ranges, ranges of different kinds
- and symbolic ranges. TODO, we may be able to derive anti-ranges
- in some cases. */
- if (vr0.type == VR_VARYING
- || vr1.type == VR_VARYING
- || vr0.type != vr1.type
- || symbolic_range_p (&vr0)
- || symbolic_range_p (&vr1))
+ and symbolic ranges. As an exception, we allow BIT_AND_EXPR
+ because we may be able to derive a useful range even if one of
+ the operands is VR_VARYING or symbolic range. TODO, we may be
+ able to derive anti-ranges in some cases. */
+ if (code != BIT_AND_EXPR
+ && (vr0.type == VR_VARYING
+ || vr1.type == VR_VARYING
+ || vr0.type != vr1.type
+ || symbolic_range_p (&vr0)
+ || symbolic_range_p (&vr1)))
{
set_value_range_to_varying (vr);
return;
@@ -1406,6 +1410,31 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
min = vrp_int_const_binop (code, vr0.min, vr1.max);
max = vrp_int_const_binop (code, vr0.max, vr1.min);
}
+ else if (code == BIT_AND_EXPR)
+ {
+ if (vr0.type == VR_RANGE
+ && vr0.min == vr0.max
+ && tree_expr_nonnegative_p (vr0.max)
+ && TREE_CODE (vr0.max) == INTEGER_CST)
+ {
+ min = fold_convert (TREE_TYPE (expr), integer_zero_node);
+ max = vr0.max;
+ }
+ else if (vr1.type == VR_RANGE
+ && vr1.min == vr1.max
+ && tree_expr_nonnegative_p (vr1.max)
+ && TREE_CODE (vr1.max) == INTEGER_CST)
+ {
+ vr0.type = VR_RANGE;
+ min = fold_convert (TREE_TYPE (expr), integer_zero_node);
+ max = vr1.max;
+ }
+ else
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+ }
else
gcc_unreachable ();
OpenPOWER on IntegriCloud