Commit 8b201bc5 by Richard Guenther Committed by Richard Biener

tree-vrp.c (zero_nonzero_bits_from_vr): Make sure to always return true for…

tree-vrp.c (zero_nonzero_bits_from_vr): Make sure to always return true for constant integer ranges.

2011-08-05  Richard Guenther  <rguenther@suse.de>

	* tree-vrp.c (zero_nonzero_bits_from_vr): Make sure to always
	return true for constant integer ranges.
	(extract_range_from_binary_expr_1): Simplify BIT_AND_EXPR and
	BIT_IOR_EXPR handling.

	* gcc.dg/tree-ssa/vrp51.c: Disable CCP.
	* gcc.dg/tree-ssa/vrp52.c: Likewise.
	* gcc.dg/tree-ssa/vrp53.c: Likewise.

From-SVN: r177423
parent 44997fe4
2011-08-05 Richard Guenther <rguenther@suse.de>
* tree-vrp.c (zero_nonzero_bits_from_vr): Make sure to always
return true for constant integer ranges.
(extract_range_from_binary_expr_1): Simplify BIT_AND_EXPR and
BIT_IOR_EXPR handling.
2011-08-04 Kai Tietz <ktietz@redhat.com> 2011-08-04 Kai Tietz <ktietz@redhat.com>
* config/i386/i386.c (setup_incoming_varargs_ms_64): Set * config/i386/i386.c (setup_incoming_varargs_ms_64): Set
......
2011-08-05 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/vrp51.c: Disable CCP.
* gcc.dg/tree-ssa/vrp52.c: Likewise.
* gcc.dg/tree-ssa/vrp53.c: Likewise.
2011-08-04 Mikael Morin <mikael.morin@sfr.fr> 2011-08-04 Mikael Morin <mikael.morin@sfr.fr>
* gfortran.dg/dependency_26.f90: Add a module to the cleanup directive. * gfortran.dg/dependency_26.f90: Add a module to the cleanup directive.
......
/* PR tree-optimization/28632 */ /* PR tree-optimization/28632 */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -ftree-vrp" } */ /* { dg-options "-O2 -ftree-vrp -fno-tree-ccp" } */
/* { dg-require-effective-target int32plus } */ /* { dg-require-effective-target int32plus } */
void void
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-vrp1" } */ /* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-ccp" } */
int int
foo (unsigned int i, unsigned int j) foo (unsigned int i, unsigned int j)
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-vrp1" } */ /* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-ccp" } */
int int
f1 (int x) f1 (int x)
......
...@@ -2141,15 +2141,18 @@ static bool ...@@ -2141,15 +2141,18 @@ static bool
zero_nonzero_bits_from_vr (value_range_t *vr, double_int *may_be_nonzero, zero_nonzero_bits_from_vr (value_range_t *vr, double_int *may_be_nonzero,
double_int *must_be_nonzero) double_int *must_be_nonzero)
{ {
may_be_nonzero->low = ALL_ONES;
may_be_nonzero->high = ALL_ONES;
must_be_nonzero->low = 0;
must_be_nonzero->high = 0;
if (range_int_cst_p (vr)) if (range_int_cst_p (vr))
{ {
if (range_int_cst_singleton_p (vr)) if (range_int_cst_singleton_p (vr))
{ {
*may_be_nonzero = tree_to_double_int (vr->min); *may_be_nonzero = tree_to_double_int (vr->min);
*must_be_nonzero = *may_be_nonzero; *must_be_nonzero = *may_be_nonzero;
return true;
} }
if (tree_int_cst_sgn (vr->min) >= 0) else if (tree_int_cst_sgn (vr->min) >= 0)
{ {
double_int dmin = tree_to_double_int (vr->min); double_int dmin = tree_to_double_int (vr->min);
double_int dmax = tree_to_double_int (vr->max); double_int dmax = tree_to_double_int (vr->max);
...@@ -2174,13 +2177,9 @@ zero_nonzero_bits_from_vr (value_range_t *vr, double_int *may_be_nonzero, ...@@ -2174,13 +2177,9 @@ zero_nonzero_bits_from_vr (value_range_t *vr, double_int *may_be_nonzero,
may_be_nonzero->low |= mask; may_be_nonzero->low |= mask;
must_be_nonzero->low &= ~mask; must_be_nonzero->low &= ~mask;
} }
return true;
} }
return true;
} }
may_be_nonzero->low = ALL_ONES;
may_be_nonzero->high = ALL_ONES;
must_be_nonzero->low = 0;
must_be_nonzero->high = 0;
return false; return false;
} }
...@@ -2638,59 +2637,17 @@ extract_range_from_binary_expr_1 (value_range_t *vr, ...@@ -2638,59 +2637,17 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
} }
else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR) else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR)
{ {
bool vr0_int_cst_singleton_p, vr1_int_cst_singleton_p;
bool int_cst_range0, int_cst_range1; bool int_cst_range0, int_cst_range1;
double_int may_be_nonzero0, may_be_nonzero1; double_int may_be_nonzero0, may_be_nonzero1;
double_int must_be_nonzero0, must_be_nonzero1; double_int must_be_nonzero0, must_be_nonzero1;
value_range_t *non_singleton_vr;
tree singleton_val;
vr0_int_cst_singleton_p = range_int_cst_singleton_p (&vr0);
vr1_int_cst_singleton_p = range_int_cst_singleton_p (&vr1);
int_cst_range0 = zero_nonzero_bits_from_vr (&vr0, &may_be_nonzero0, int_cst_range0 = zero_nonzero_bits_from_vr (&vr0, &may_be_nonzero0,
&must_be_nonzero0); &must_be_nonzero0);
int_cst_range1 = zero_nonzero_bits_from_vr (&vr1, &may_be_nonzero1, int_cst_range1 = zero_nonzero_bits_from_vr (&vr1, &may_be_nonzero1,
&must_be_nonzero1); &must_be_nonzero1);
singleton_val = (vr0_int_cst_singleton_p ? vr0.min : vr1.min);
non_singleton_vr = (vr0_int_cst_singleton_p ? &vr1 : &vr0);
type = VR_RANGE; type = VR_RANGE;
if (vr0_int_cst_singleton_p && vr1_int_cst_singleton_p) if (code == BIT_AND_EXPR)
min = max = int_const_binop (code, vr0.max, vr1.max);
else if ((vr0_int_cst_singleton_p || vr1_int_cst_singleton_p)
&& (integer_zerop (singleton_val)
|| integer_all_onesp (singleton_val)))
{
/* If one of the operands is zero for and-case, we know that
* the whole expression evaluates zero.
If one of the operands has all bits set to one for
or-case, we know that the whole expression evaluates
to this one. */
min = max = singleton_val;
if ((code == BIT_IOR_EXPR
&& integer_zerop (singleton_val))
|| (code == BIT_AND_EXPR
&& integer_all_onesp (singleton_val)))
/* If one of the operands has all bits set to one, we know
that the whole expression evaluates to the other one for
the and-case.
If one of the operands is zero, we know that the whole
expression evaluates to the other one for the or-case. */
{
type = non_singleton_vr->type;
min = non_singleton_vr->min;
max = non_singleton_vr->max;
}
set_value_range (vr, type, min, max, NULL);
return;
}
else if (!int_cst_range0 && !int_cst_range1)
{
set_value_range_to_varying (vr);
return;
}
else if (code == BIT_AND_EXPR)
{ {
min = double_int_to_tree (expr_type, min = double_int_to_tree (expr_type,
double_int_and (must_be_nonzero0, double_int_and (must_be_nonzero0,
...@@ -2698,9 +2655,9 @@ extract_range_from_binary_expr_1 (value_range_t *vr, ...@@ -2698,9 +2655,9 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
max = double_int_to_tree (expr_type, max = double_int_to_tree (expr_type,
double_int_and (may_be_nonzero0, double_int_and (may_be_nonzero0,
may_be_nonzero1)); may_be_nonzero1));
if (TREE_OVERFLOW (min) || tree_int_cst_sgn (min) < 0) if (tree_int_cst_sgn (min) < 0)
min = NULL_TREE; min = NULL_TREE;
if (TREE_OVERFLOW (max) || tree_int_cst_sgn (max) < 0) if (tree_int_cst_sgn (max) < 0)
max = NULL_TREE; max = NULL_TREE;
if (int_cst_range0 && tree_int_cst_sgn (vr0.min) >= 0) if (int_cst_range0 && tree_int_cst_sgn (vr0.min) >= 0)
{ {
...@@ -2717,15 +2674,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr, ...@@ -2717,15 +2674,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
max = vr1.max; max = vr1.max;
} }
} }
else if (!int_cst_range0 else if (code == BIT_IOR_EXPR)
|| !int_cst_range1
|| tree_int_cst_sgn (vr0.min) < 0
|| tree_int_cst_sgn (vr1.min) < 0)
{
set_value_range_to_varying (vr);
return;
}
else
{ {
min = double_int_to_tree (expr_type, min = double_int_to_tree (expr_type,
double_int_ior (must_be_nonzero0, double_int_ior (must_be_nonzero0,
...@@ -2733,13 +2682,22 @@ extract_range_from_binary_expr_1 (value_range_t *vr, ...@@ -2733,13 +2682,22 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
max = double_int_to_tree (expr_type, max = double_int_to_tree (expr_type,
double_int_ior (may_be_nonzero0, double_int_ior (may_be_nonzero0,
may_be_nonzero1)); may_be_nonzero1));
if (TREE_OVERFLOW (min) || tree_int_cst_sgn (min) < 0) if (tree_int_cst_sgn (max) < 0)
min = vr0.min;
else
min = vrp_int_const_binop (MAX_EXPR, min, vr0.min);
if (TREE_OVERFLOW (max) || tree_int_cst_sgn (max) < 0)
max = NULL_TREE; max = NULL_TREE;
min = vrp_int_const_binop (MAX_EXPR, min, vr1.min); if (int_cst_range0)
{
if (tree_int_cst_sgn (min) < 0)
min = vr0.min;
else
min = vrp_int_const_binop (MAX_EXPR, min, vr0.min);
}
if (int_cst_range1)
min = vrp_int_const_binop (MAX_EXPR, min, vr1.min);
}
else
{
set_value_range_to_varying (vr);
return;
} }
} }
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment