Commit a3b196e3 by Jeff Law Committed by Jeff Law

tree-vrp.c (extract_range_from_unary_expr): Derive ranges for type conversions…

tree-vrp.c (extract_range_from_unary_expr): Derive ranges for type conversions of a VR_VARYING source to a wider type.


	* tree-vrp.c (extract_range_from_unary_expr): Derive ranges for
	type conversions of a VR_VARYING source to a wider type.

	* gcc.dg/tree-ssa/vrp28.c: New test.

From-SVN: r112256
parent ec23ed60
2006-03-21 Jeff Law <law@redhat.com>
* tree-vrp.c (extract_range_from_unary_expr): Derive ranges for
type conversions of a VR_VARYING source to a wider type.
2006-03-21 Eric Botcazou <ebotcazou@libertysurf.fr> 2006-03-21 Eric Botcazou <ebotcazou@libertysurf.fr>
* config.gcc (i[34567]86-*-solaris2*): Add config/sol2-10.h to * config.gcc (i[34567]86-*-solaris2*): Add config/sol2-10.h to
...@@ -106,7 +111,6 @@ ...@@ -106,7 +111,6 @@
* tree-ssa-structalias.c (intra_create_variable_infos): Fortran * tree-ssa-structalias.c (intra_create_variable_infos): Fortran
alias semantics is specified by flag_argument_noalias > 2. alias semantics is specified by flag_argument_noalias > 2.
2006-03-20 Jeff Law <law@redhat.com>
* tree-pass.h (pass_phi_only_copy_prop): Delete. * tree-pass.h (pass_phi_only_copy_prop): Delete.
(pass_phi_only_cprop): Declare. (pass_phi_only_cprop): Declare.
......
2006-03-21 Jeff Law <law@redhat.com>
* gcc.dg/tree-ssa/vrp28.c: New test.
2006-03-21 Eric Botcazou <ebotcazou@libertysurf.fr> 2006-03-21 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/builtins-config.h (Solaris case): Define HAVE_C99_RUNTIME * gcc.dg/builtins-config.h (Solaris case): Define HAVE_C99_RUNTIME
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-vrp1" } */
int f(_Bool a)
{
int t = a;
if (t != 2)
return 0;
return 1;
}
int f1(unsigned char a)
{
int t = a;
if (t != 256)
return 0;
return 1;
}
int f3 (unsigned char c)
{
int i = c;
if (i < 0 || i > 255)
return -1;
else
return 0;
}
/* { dg-final { scan-tree-dump-times "if " 0 "vrp1" } } * /
/* { dg-final { cleanup-tree-dump "vrp1" } } */
...@@ -1641,14 +1641,12 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) ...@@ -1641,14 +1641,12 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
return; return;
} }
/* Refuse to operate on varying and symbolic ranges. Also, if the /* Refuse to operate on symbolic ranges, or if neither operand is
operand is neither a pointer nor an integral type, set the a pointer or integral type. */
resulting range to VARYING. TODO, in some cases we may be able if ((!INTEGRAL_TYPE_P (TREE_TYPE (op0))
to derive anti-ranges (like nonzero values). */ && !POINTER_TYPE_P (TREE_TYPE (op0)))
if (vr0.type == VR_VARYING || (vr0.type != VR_VARYING
|| (!INTEGRAL_TYPE_P (TREE_TYPE (op0)) && symbolic_range_p (&vr0)))
&& !POINTER_TYPE_P (TREE_TYPE (op0)))
|| symbolic_range_p (&vr0))
{ {
set_value_range_to_varying (vr); set_value_range_to_varying (vr);
return; return;
...@@ -1681,20 +1679,36 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) ...@@ -1681,20 +1679,36 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
or equal to the new max, then we can safely use the newly or equal to the new max, then we can safely use the newly
computed range for EXPR. This allows us to compute computed range for EXPR. This allows us to compute
accurate ranges through many casts. */ accurate ranges through many casts. */
if (vr0.type == VR_RANGE) if (vr0.type == VR_RANGE
|| (vr0.type == VR_VARYING
&& TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)))
{ {
tree new_min, new_max; tree new_min, new_max, orig_min, orig_max;
/* Convert VR0's min/max to OUTER_TYPE. */ /* Convert the input operand min/max to OUTER_TYPE. If
new_min = fold_convert (outer_type, vr0.min); the input has no range information, then use the min/max
new_max = fold_convert (outer_type, vr0.max); for the input's type. */
if (vr0.type == VR_RANGE)
{
orig_min = vr0.min;
orig_max = vr0.max;
}
else
{
orig_min = TYPE_MIN_VALUE (inner_type);
orig_max = TYPE_MAX_VALUE (inner_type);
}
new_min = fold_convert (outer_type, orig_min);
new_max = fold_convert (outer_type, orig_max);
/* Verify the new min/max values are gimple values and /* Verify the new min/max values are gimple values and
that they compare equal to VR0's min/max values. */ that they compare equal to the orignal input's
min/max values. */
if (is_gimple_val (new_min) if (is_gimple_val (new_min)
&& is_gimple_val (new_max) && is_gimple_val (new_max)
&& tree_int_cst_equal (new_min, vr0.min) && tree_int_cst_equal (new_min, orig_min)
&& tree_int_cst_equal (new_max, vr0.max) && tree_int_cst_equal (new_max, orig_max)
&& compare_values (new_min, new_max) <= 0 && compare_values (new_min, new_max) <= 0
&& compare_values (new_min, new_max) >= -1) && compare_values (new_min, new_max) >= -1)
{ {
...@@ -1717,6 +1731,16 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) ...@@ -1717,6 +1731,16 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
} }
} }
/* Conversion of a VR_VARYING value to a wider type can result
in a usable range. So wait until after we've handled conversions
before dropping the result to VR_VARYING if we had a source
operand that is VR_VARYING. */
if (vr0.type == VR_VARYING)
{
set_value_range_to_varying (vr);
return;
}
/* Apply the operation to each end of the range and see what we end /* Apply the operation to each end of the range and see what we end
up with. */ up with. */
if (code == NEGATE_EXPR if (code == NEGATE_EXPR
......
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