re PR tree-optimization/25485 (VRP misses an "if" with TRUTH_AND_EXPR statement that could be optimized away)

gcc/
	PR tree-optimization/25485
	* tree-vrp.c (extract_range_from_binary_expr): Handle cases
	where one of the operands of TRUTH_AND_EXPR and TRUTH_OR_EXPR
	is known to be false and true, respectively.

gcc/testsuite/
	PR tree-optimization/25485
	* gcc.dg/tree-ssa/pr25485.c: New.

From-SVN: r109704
This commit is contained in:
Kazu Hirata 2006-01-14 15:42:11 +00:00 committed by Kazu Hirata
parent a916f21d3c
commit 9b61327b89
4 changed files with 72 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2006-01-14 Kazu Hirata <kazu@codesourcery.com>
PR tree-optimization/25485
* tree-vrp.c (extract_range_from_binary_expr): Handle cases
where one of the operands of TRUTH_AND_EXPR and TRUTH_OR_EXPR
is known to be false and true, respectively.
2006-01-14 Richard Guenther <rguenther@suse.de>
PR tree-optimization/22548

View File

@ -1,3 +1,8 @@
2006-01-14 Kazu Hirata <kazu@codesourcery.com>
PR tree-optimization/25485
* gcc.dg/tree-ssa/pr25485.c: New.
2006-01-14 Richard Guenther <rguenther@suse.de>
PR tree-optimization/22548

View File

@ -0,0 +1,17 @@
/* PR tree-optimization/25485
VRP did not fold TRUTH_AND_EXPR. Make sure it does now. */
/* { dg-options "-O2 -fdump-tree-vrp" } */
int
foo (int a, int b)
{
if (a > 50)
return 19;
if (a > 63 && b < 50)
return 17;
return 31;
}
/* { dg-final { scan-tree-dump-times "if" 1 "vrp"} } */
/* { dg-final { cleanup-tree-dump "vrp" } } */

View File

@ -1230,6 +1230,8 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
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
&& code != TRUTH_AND_EXPR
&& code != TRUTH_OR_EXPR
&& (vr0.type == VR_VARYING
|| vr1.type == VR_VARYING
|| vr0.type != vr1.type
@ -1277,9 +1279,47 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
|| code == TRUTH_OR_EXPR
|| code == TRUTH_XOR_EXPR)
{
/* Boolean expressions cannot be folded with int_const_binop. */
min = fold_binary (code, TREE_TYPE (expr), vr0.min, vr1.min);
max = fold_binary (code, TREE_TYPE (expr), vr0.max, vr1.max);
/* If one of the operands is zero, we know that the whole
expression evaluates zero. */
if (code == TRUTH_AND_EXPR
&& ((vr0.type == VR_RANGE
&& integer_zerop (vr0.min)
&& integer_zerop (vr0.max))
|| (vr1.type == VR_RANGE
&& integer_zerop (vr1.min)
&& integer_zerop (vr1.max))))
{
type = VR_RANGE;
min = max = build_int_cst (TREE_TYPE (expr), 0);
}
/* If one of the operands is one, we know that the whole
expression evaluates one. */
else if (code == TRUTH_OR_EXPR
&& ((vr0.type == VR_RANGE
&& integer_onep (vr0.min)
&& integer_onep (vr0.max))
|| (vr1.type == VR_RANGE
&& integer_onep (vr1.min)
&& integer_onep (vr1.max))))
{
type = VR_RANGE;
min = max = build_int_cst (TREE_TYPE (expr), 1);
}
else if (vr0.type != VR_VARYING
&& vr1.type != VR_VARYING
&& vr0.type == vr1.type
&& !symbolic_range_p (&vr0)
&& !symbolic_range_p (&vr1))
{
/* Boolean expressions cannot be folded with int_const_binop. */
min = fold_binary (code, TREE_TYPE (expr), vr0.min, vr1.min);
max = fold_binary (code, TREE_TYPE (expr), vr0.max, vr1.max);
}
else
{
set_value_range_to_varying (vr);
return;
}
}
else if (code == PLUS_EXPR
|| code == MIN_EXPR