Commit b47ee386 by Richard Guenther Committed by Richard Biener

tree-vrp.c (extract_range_from_unary_expr): Handle all conversions.

2008-04-03  Richard Guenther  <rguenther@suse.de>

	* tree-vrp.c (extract_range_from_unary_expr): Handle all
	conversions.  Simplify code.

	* gcc.dg/tree-ssa/vrp43.c: New testcase.
	* gcc.dg/tree-ssa/vrp44.c: Likewise.
	* gcc.dg/tree-ssa/vrp45.c: Likewise.

From-SVN: r133866
parent 2a7428c0
2008-04-03 Richard Guenther <rguenther@suse.de>
* tree-vrp.c (extract_range_from_unary_expr): Handle all
conversions. Simplify code.
2008-04-03 Kaz Kojima <kkojima@gcc.gnu.org> 2008-04-03 Kaz Kojima <kkojima@gcc.gnu.org>
* config/sh/sh.c (sh_output_mi_thunk): Free cfun. * config/sh/sh.c (sh_output_mi_thunk): Free cfun.
......
2008-04-03 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/vrp43.c: New testcase.
* gcc.dg/tree-ssa/vrp44.c: Likewise.
* gcc.dg/tree-ssa/vrp45.c: Likewise.
2008-04-03 Jakub Jelinek <jakub@redhat.com> 2008-04-03 Jakub Jelinek <jakub@redhat.com>
PR c++/35741 PR c++/35741
/* { dg-do run } */
/* { dg-options "-O2" } */
int __attribute__((noinline))
foo(int i)
{
if (i != 0)
{
char c = (char)i;
return c != 0;
}
return 0;
}
extern void abort (void);
int main()
{
if (foo(0xff00))
abort ();
return 0;
}
/* { dg-do link } */
/* { dg-options "-O2" } */
extern void link_error (void);
void test1(int i)
{
if (i >= -5 && i <= 8)
{
unsigned int j = i + 1;
if (j == -5)
link_error ();
if (j == 10)
link_error ();
}
}
void test2(unsigned int i)
{
if (i >= -5 || i <= 8)
{
int j = i;
if (j == -6)
link_error ();
if (j == 9)
link_error ();
}
}
int main() { return 0; }
/* { dg-do link } */
/* { dg-options "-O2" } */
extern void link_error (void);
void foo (int i)
{
if (i > -128 && i < 127)
{
unsigned char k = i;
if (k == 0x80)
link_error ();
if (k == 0x7f)
link_error ();
}
}
int main() { return 0; }
...@@ -2350,72 +2350,64 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code, ...@@ -2350,72 +2350,64 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
} }
/* Handle unary expressions on integer ranges. */ /* Handle unary expressions on integer ranges. */
if (code == NOP_EXPR || code == CONVERT_EXPR) if ((code == NOP_EXPR
|| code == CONVERT_EXPR)
&& INTEGRAL_TYPE_P (type)
&& INTEGRAL_TYPE_P (TREE_TYPE (op0)))
{ {
tree inner_type = TREE_TYPE (op0); tree inner_type = TREE_TYPE (op0);
tree outer_type = type; tree outer_type = type;
/* If VR0 represents a simple range, then try to convert /* Always use base-types here. This is important for the
the min and max values for the range to the same type correct signedness. */
as OUTER_TYPE. If the results compare equal to VR0's if (TREE_TYPE (inner_type))
min and max values and the new min is still less than inner_type = TREE_TYPE (inner_type);
or equal to the new max, then we can safely use the newly if (TREE_TYPE (outer_type))
computed range for EXPR. This allows us to compute outer_type = TREE_TYPE (outer_type);
accurate ranges through many casts. */
if ((vr0.type == VR_RANGE
&& !overflow_infinity_range_p (&vr0))
|| (vr0.type == VR_VARYING
&& TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)))
{
tree new_min, new_max, orig_min, orig_max;
/* Convert the input operand min/max to OUTER_TYPE. If /* If VR0 is varying and we increase the type precision, assume
the input has no range information, then use the min/max a full range for the following transformation. */
for the input's type. */ if (vr0.type == VR_VARYING
if (vr0.type == VR_RANGE) && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type))
{
orig_min = vr0.min;
orig_max = vr0.max;
}
else
{ {
orig_min = TYPE_MIN_VALUE (inner_type); vr0.type = VR_RANGE;
orig_max = TYPE_MAX_VALUE (inner_type); vr0.min = TYPE_MIN_VALUE (inner_type);
vr0.max = TYPE_MAX_VALUE (inner_type);
} }
new_min = fold_convert (outer_type, orig_min); /* If VR0 is a constant range or anti-range and the conversion is
new_max = fold_convert (outer_type, orig_max); not truncating we can convert the min and max values and
canonicalize the resulting range. Otherwise we can do the
/* Verify the new min/max values are gimple values and conversion if the size of the range is less than what the
that they compare equal to the original input's precision of the target type can represent and the range is
min/max values. */ not an anti-range. */
if (is_gimple_val (new_min) if ((vr0.type == VR_RANGE
&& is_gimple_val (new_max) || vr0.type == VR_ANTI_RANGE)
&& tree_int_cst_equal (new_min, orig_min) && TREE_CODE (vr0.min) == INTEGER_CST
&& tree_int_cst_equal (new_max, orig_max) && TREE_CODE (vr0.max) == INTEGER_CST
&& (!is_overflow_infinity (new_min) && !is_overflow_infinity (vr0.min)
|| !is_overflow_infinity (new_max)) && !is_overflow_infinity (vr0.max)
&& (cmp = compare_values (new_min, new_max)) <= 0 && (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
&& cmp >= -1) || (vr0.type == VR_RANGE
{ && integer_zerop (int_const_binop (RSHIFT_EXPR,
set_value_range (vr, VR_RANGE, new_min, new_max, vr->equiv); int_const_binop (MINUS_EXPR, vr0.max, vr0.min, 0),
size_int (TYPE_PRECISION (outer_type)), 0)))))
{
tree new_min, new_max;
new_min = force_fit_type_double (outer_type,
TREE_INT_CST_LOW (vr0.min),
TREE_INT_CST_HIGH (vr0.min), 0, 0);
new_max = force_fit_type_double (outer_type,
TREE_INT_CST_LOW (vr0.max),
TREE_INT_CST_HIGH (vr0.max), 0, 0);
set_and_canonicalize_value_range (vr, vr0.type,
new_min, new_max, NULL);
return; return;
} }
}
/* When converting types of different sizes, set the result to
VARYING. Things like sign extensions and precision loss may
change the range. For instance, if x_3 is of type 'long long
int' and 'y_5 = (unsigned short) x_3', if x_3 is ~[0, 0], it
is impossible to know at compile time whether y_5 will be
~[0, 0]. */
if (TYPE_SIZE (inner_type) != TYPE_SIZE (outer_type)
|| TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
{
set_value_range_to_varying (vr); set_value_range_to_varying (vr);
return; return;
} }
}
/* Conversion of a VR_VARYING value to a wider type can result /* Conversion of a VR_VARYING value to a wider type can result
in a usable range. So wait until after we've handled conversions in a usable range. So wait until after we've handled conversions
......
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