Commit 7d5a0f1b by Richard Guenther Committed by Richard Biener

re PR tree-optimization/50729 (Silent code gen fault: Value range propagation…

re PR tree-optimization/50729 (Silent code gen fault: Value range propagation seems to propagate values across narrowing/widening)

2011-10-17  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/50729
	* tree-vrp.c (extract_range_from_unary_expr_1): Remove
	redundant test.
	(simplify_conversion_using_ranges): Properly test the
	intermediate result.

	* gcc.dg/torture/pr50729.c: New testcase.

From-SVN: r180087
parent b9bd6f74
2011-10-17 Richard Guenther <rguenther@suse.de>
PR tree-optimization/50729
* tree-vrp.c (extract_range_from_unary_expr_1): Remove
redundant test.
(simplify_conversion_using_ranges): Properly test the
intermediate result.
2011-10-15 Tom Tromey <tromey@redhat.com> 2011-10-15 Tom Tromey <tromey@redhat.com>
Dodji Seketeli <dodji@redhat.com> Dodji Seketeli <dodji@redhat.com>
2011-10-17 Richard Guenther <rguenther@suse.de>
PR tree-optimization/50729
* gcc.dg/torture/pr50729.c: New testcase.
2011-10-15 Tom Tromey <tromey@redhat.com> 2011-10-15 Tom Tromey <tromey@redhat.com>
Dodji Seketeli <dodji@redhat.com> Dodji Seketeli <dodji@redhat.com>
......
/* { dg-do run } */
/* { dg-require-effective-target int32plus } */
extern void abort (void);
unsigned short __attribute__((noinline))
foo (int i)
{
if (i >= 0
&& i <= 0x400000)
return (unsigned short)(signed char)i;
return i;
}
int main()
{
int i;
for (i = 0; i < 0xffff; ++i)
if (foo(i) != (unsigned short)(signed char) i)
abort ();
return 0;
}
...@@ -2913,15 +2913,10 @@ extract_range_from_unary_expr_1 (value_range_t *vr, ...@@ -2913,15 +2913,10 @@ extract_range_from_unary_expr_1 (value_range_t *vr,
determining if it evaluates to NULL [0, 0] or non-NULL (~[0, 0]). */ determining if it evaluates to NULL [0, 0] or non-NULL (~[0, 0]). */
if (POINTER_TYPE_P (type)) if (POINTER_TYPE_P (type))
{ {
if (CONVERT_EXPR_CODE_P (code)) if (range_is_nonnull (&vr0))
{ set_value_range_to_nonnull (vr, type);
if (range_is_nonnull (&vr0)) else if (range_is_null (&vr0))
set_value_range_to_nonnull (vr, type); set_value_range_to_null (vr, type);
else if (range_is_null (&vr0))
set_value_range_to_null (vr, type);
else
set_value_range_to_varying (vr);
}
else else
set_value_range_to_varying (vr); set_value_range_to_varying (vr);
return; return;
...@@ -7288,10 +7283,17 @@ simplify_conversion_using_ranges (gimple stmt) ...@@ -7288,10 +7283,17 @@ simplify_conversion_using_ranges (gimple stmt)
TYPE_UNSIGNED (TREE_TYPE (middleop))); TYPE_UNSIGNED (TREE_TYPE (middleop)));
middlemax = double_int_ext (innermax, TYPE_PRECISION (TREE_TYPE (middleop)), middlemax = double_int_ext (innermax, TYPE_PRECISION (TREE_TYPE (middleop)),
TYPE_UNSIGNED (TREE_TYPE (middleop))); TYPE_UNSIGNED (TREE_TYPE (middleop)));
/* If the middle values do not represent a proper range fail. */ /* If the middle values are not equal to the original values fail.
if (double_int_cmp (middlemin, middlemax, But only if the inner cast truncates (thus we ignore differences
TYPE_UNSIGNED (TREE_TYPE (middleop))) > 0) in extension to handle the case going from a range to an anti-range
and back). */
if ((TYPE_PRECISION (TREE_TYPE (innerop))
> TYPE_PRECISION (TREE_TYPE (middleop)))
&& (!double_int_equal_p (innermin, middlemin)
|| !double_int_equal_p (innermax, middlemax)))
return false; return false;
/* Require that the final conversion applied to both the original
and the intermediate range produces the same result. */
if (!double_int_equal_p (double_int_ext (middlemin, if (!double_int_equal_p (double_int_ext (middlemin,
TYPE_PRECISION (finaltype), TYPE_PRECISION (finaltype),
TYPE_UNSIGNED (finaltype)), TYPE_UNSIGNED (finaltype)),
......
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