re PR tree-optimization/25382 (VRP does not get a range from BIT_AND_EXPR if the second operand is constant)

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.

From-SVN: r108898
This commit is contained in:
Kazu Hirata 2005-12-21 05:58:02 +00:00 committed by Kazu Hirata
parent 486aa8045c
commit 29c8f8c27b
4 changed files with 66 additions and 7 deletions

View File

@ -1,3 +1,9 @@
2005-12-21 Kazu Hirata <kazu@codesourcery.com>
PR tree-optimization/25382.
* tree-vrp.c (extract_range_from_binary_expr): Extract a range
from BIT_AND_EXPR.
2005-12-21 Janis Johnson <janis187@us.ibm.com>
Ben Elliston <bje@au.ibm.com>

View File

@ -1,3 +1,8 @@
2005-12-21 Kazu Hirata <kazu@codesourcery.com>
PR tree-optimization/25382.
* gcc.dg/tree-ssa/pr25382.c: New.
2005-12-20 Richard Guenther <rguenther@suse.de>
PR middle-end/24306

View File

@ -0,0 +1,19 @@
/* PR tree-optimization/25382
VRP used to ignore BIT_AND_EXPRs for the purpose of distilling ranges.
Check that VRP now gets ranges from BIT_AND_EXPRs. */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-vrp" } */
int
foo (int a)
{
int b = a & 0xff;
if (b > 300)
return 2;
else
return 1;
}
/* { dg-final { scan-tree-dump-times "Folding predicate b_.* > 300 to 0" 1 "vrp" } } */
/* { dg-final { cleanup-tree-dump "vrp" } } */

View File

@ -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 ();